Oracle
 sql >> база данни >  >> RDS >> Oracle

SQL:Търсене в списък от колони с дадена стойност (в ред)

Това не е нормална част от функционалността на базата данни. Вие обаче не сте първият човек, който е поискал това или нещо подобно.

Решението изисква две неща. Първият е речникът на данните; базата данни на Oracle не поддържа Reflection, но идва с набор от изгледи, които ни дават метаданни за обектите на нашата база данни. В този случай имаме нужда от user_tab_columns , което ще ни даде колоните за дадена таблица. Второто нещо е динамичен SQL; това е способността да се сглоби SQL заявка по време на изпълнение и след това да се изпълни. Има няколко начина да направите това, но обикновено референтните курсори са достатъчни.

Следният код е доказателство за концепцията. Отнема четири параметъра:

  1. името на таблицата, която искате да търсите
  2. името на основната ключова колона на тази таблица
  3. стойността на първичния ключ, по която искате да ограничите
  4. стойността, която искате да търсите.

Той е rough'n'ready, така че може да се наложи да го редактирате, за да подредите изхода или да направите програмата по-гъвкава.

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;
/

Както можете да видите, динамичният SQL е труден за четене. По-трудно е да се отстраняват грешки :) Така че е добра идея да имате средство за показване на крайния израз.

Както и да е, ето резултатите:

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. История на базата данни за използване от клиента

  2. Как да създадете ненулево ограничение в oracle

  3. Как да избягате от запетая и двоен кавичка едновременно за CSV файл?

  4. Доставчикът на ADO.NET „Oracle.ManagedDataAccess.Client“ или не е регистриран в конфигурационния файл на машината или приложението, или не може да бъде зареден

  5. Възможно ли е да се препълни тип Oracle NUMBER?