sql >> Databáze >  >> RDS >> Oracle

SQL:Vyhledejte seznam sloupců s danou hodnotou (v rámci řádku)

Toto není běžná funkce databáze. Nejste však první, kdo o to nebo něco podobného požádal.

Řešení vyžaduje dvě věci. První je datový slovník; databáze Oracle nepodporuje Reflection, ale přichází se sadou pohledů, které nám poskytují metadata o našich databázových objektech. V tomto případě potřebujeme user_tab_columns , který nám poskytne sloupce pro danou tabulku. Druhá věc je dynamické SQL; to je schopnost sestavit SQL dotaz za běhu a poté jej spustit. Existuje několik způsobů, jak toho dosáhnout, ale obvykle postačují referenční kurzory.

Následující kód je důkazem konceptu. Vyžaduje čtyři parametry:

  1. název tabulky, kterou chcete prohledávat
  2. název primárního klíčového sloupce tabulky
  3. hodnota primárního klíče, kterou chcete omezit
  4. hodnotu, kterou chcete vyhledat.

Je hrubý'n'ready, takže ho možná budete muset upravit, aby se výstup uklidil nebo aby byl program flexibilnější.

create or replace procedure search_cols
  (tname in user_tables.table_name%type
   , pk_col in user_tab_columns.column_name%type
   , pk in number
   , val in number )
is
    firstcol boolean := true;
    stmt varchar2(32767);
    result varchar2(32767);
    rc sys_refcursor;
begin
    stmt := 'select ';
    << projection >>
    for lrec in ( select column_name from user_tab_columns
                  where table_name = tname
                  and column_name != pk_col
                  and data_type = 'NUMBER'
                  order by column_id )
    loop
        if not firstcol then
            stmt := stmt || chr(10) || '||'',''||';
        else
            firstcol := false;
        end if;
        stmt := stmt || ' case when '|| lrec.column_name||' = '|| val ||
                           ' then '''|| lrec.column_name || ''' else null end';
    end loop projection;
    stmt := stmt || chr(10)|| ' from '||tname||' where '|| pk_col || ' = '|| pk;
    --  dbms_output.put_line(stmt);
    open rc for stmt;
    fetch rc into result;
    close rc;
    dbms_output.put_line(tname || '::' || val || ' found in '||result);
end search_cols;
/

Jak vidíte, dynamické SQL je těžké číst. Je těžší to odladit :) Je tedy dobré mít způsob, jak ukázat konečné prohlášení.

Každopádně zde jsou výsledky:

SQL> set serveroutput on size unlimited
SQL> exec search_cols('T23', 'ID', 111, 10)
T23::10 found in ,COL_B,COL_C,

PL/SQL procedure successfully completed.

SQL> exec search_cols('T23', 'ID', 222, 10)
T23::10 found in COL_A,,,

PL/SQL procedure successfully completed.

SQL>


  1. Vložit pouze v případě, že se hodnoty liší od předchozího záznamu s vícenásobným vložením?

  2. Použití příkazu Python pro příkaz SQL INSERT

  3. MySQL-db lib pro Python 3.x?

  4. Jak mohu VYBRAT více sloupců v CASE WHEN na SQL Server?