Detta är inte en normal del av databasfunktionalitet. Men du är inte den första som har bett om detta, eller något liknande.
Lösningen kräver två saker. Den första är dataordboken; Oracle-databasen stöder inte Reflection men den kommer med en uppsättning vyer som ger oss metadata om våra databasobjekt. I det här fallet behöver vi user_tab_columns
, vilket ger oss kolumnerna för en given tabell. Den andra saken är dynamisk SQL; detta är förmågan att sätta ihop en SQL-fråga vid körning och sedan köra den. Det finns ett par sätt att göra detta på, men vanligtvis räcker det med referensmarkörer.
Följande kod är ett bevis på konceptet. Det krävs fyra parametrar:
- namnet på tabellen du vill söka efter
- namnet på tabellens primära nyckelkolumn
- det primära nyckelvärde som du vill begränsa med
- värdet du vill söka efter.
Den är rough'n'ready så du kan behöva redigera den för att göra ordning på utdata eller för att göra programmet mer flexibelt.
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;
/
Som du kan se är dynamisk SQL svår att läsa. Det är svårare att felsöka :) Så det är en bra idé att ha ett sätt att visa slutsatsen.
Hur som helst, här är resultaten:
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>