Oracle
 sql >> Baza danych >  >> RDS >> Oracle

SQL:Przeszukaj listę kolumn o podanej wartości (w wierszu)

To nie jest normalna funkcja bazy danych. Jednak nie jesteś pierwszą osobą, która o to poprosiła lub coś w tym stylu.

Rozwiązanie wymaga dwóch rzeczy. Pierwszy to słownik danych; baza danych Oracle nie obsługuje odbicia, ale zawiera zestaw widoków, które dostarczają nam metadanych o naszych obiektach bazy danych. W tym przypadku potrzebujemy user_tab_columns , co da nam kolumny dla danej tabeli. Druga rzecz to dynamiczny SQL; jest to możliwość złożenia zapytania SQL w czasie wykonywania, a następnie jego wykonania. Można to zrobić na kilka sposobów, ale zazwyczaj wystarczy użyć kursorów ref.

Poniższy kod jest dowodem koncepcji. Wymaga czterech parametrów:

  1. nazwa tabeli, którą chcesz przeszukać
  2. nazwa kolumny klucza podstawowego tej tabeli
  3. wartość klucza podstawowego, według której chcesz ograniczyć
  4. wartość, którą chcesz wyszukać.

Jest surowy i gotowy, więc być może będziesz musiał go edytować, aby uporządkować dane wyjściowe lub uczynić program bardziej elastycznym.

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 widać, dynamiczny SQL jest trudny do odczytania. Trudniej jest debugować :) Dlatego dobrym pomysłem jest posiadanie środków do pokazania końcowego oświadczenia.

W każdym razie oto wyniki:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy w niektórych wersjach Oracle istnieje limit zagnieżdżania skorelowanych podzapytań?

  2. UPSERT do tabeli z dynamiczną nazwą tabeli

  3. Błąd podczas próby pobrania tekstu dla błędu ORA-01804

  4. Alarm krytyczny Mavena:wersja_protokołu

  5. Jak wyświetlić listę wszystkich tabel w schemacie w Oracle SQL?