如何在 不引用 SQL表达式中的 特定列的情况下 选择所有可能包含已知特定值的记录?
例如,我知道,某个 未知 列包含值“ xxx”,并且表中有 许多列 和记录。
谢谢你。
因此,您想对数据库进行类似于Google的免费文本搜索。可以做到,但表演将是Teh Suck!Google之所以快速,是因为它在其索引上具有索引,重复的数据存储,并且通常针对这种搜索进行总体优化。
无论如何,这是使用动态SQL和Oracle数据字典的概念证明。请注意,我将列限制为要搜索的数据类型,即字符串。
SQL> set serveroutput on size unlimited SQL> declare 2 dummy varchar2(1); 3 begin 4 for r in ( select table_name, column_name from user_tab_cols 5 where data_type in ('VARCHAR2', 'CHAR', 'CLOB') ) 6 loop 7 begin 8 execute immediate 'select null from '||r.table_name 9 ||' where '||r.column_name||' like ''%&search_value%'' ' 10 ||' and rownum = 1' 11 into dummy; 12 dbms_output.put_line('Found it in >>>' 13 ||r.table_name||'.'||r.column_name); 14 exception 15 when others then 16 -- bad practice ahoy! 17 null; 18 end; 19 end loop; 20 end; 21 / Enter value for search_value: MAISIE old 9: ||' where '||r.column_name||' like ''%&search_value%'' ' new 9: ||' where '||r.column_name||' like ''%MAISIE%'' ' Found it in >>>T23.NAME PL/SQL procedure successfully completed. SQL>
一个更健壮的实现可能需要处理大小写,整个单词等。如果您使用的是10g或更高版本,则正则表达式可能会有用,但是将regex和动态SQL结合起来是一个更 有趣的 前景。
我再说一遍,表演将是Teh Suck!在大数据集上。几乎不可能进行调整,因为我们无法为每一列编制索引,并且当然不支持LIKE或类似的模糊匹配。一种替代方法是使用XQuery生成数据的XML表示,然后使用Text对其进行索引。维护这样的存储库将是开销,但是如果您需要定期使用此功能(尤其是在生产环境中),则将是一项合理的投资。
通过使用,我们可以对所有我们有权使用的表进行更广泛的搜索all_tab_cols。
all_tab_cols
for r in ( select owner, table_name, column_name from all_tab_cols where data_type in ('VARCHAR2', 'CHAR', 'CLOB') )
显然,我们需要在生成的语句中为拥有的模式添加前缀。
execute immediate 'select null from '||r.owner||'.'||r.table_name ||' where '||r.column_name||' like ''%