Sql 在Oracle数据库中动态搜索2个值
大家好 我试图在一定程度上解决这个问题,但还是有点困难 对于本例,我想在两列中找到两个值: 瓦查尔和日期 约翰1984-01-01 假设这是约翰的生日 我希望能够在2000个表中找到JOHN的值和DATE的值,让事情复杂化的是,列名不尽相同。数据类型为 下面将选择我需要的具有两个列名的所有表Sql 在Oracle数据库中动态搜索2个值,sql,oracle,Sql,Oracle,大家好 我试图在一定程度上解决这个问题,但还是有点困难 对于本例,我想在两列中找到两个值: 瓦查尔和日期 约翰1984-01-01 假设这是约翰的生日 我希望能够在2000个表中找到JOHN的值和DATE的值,让事情复杂化的是,列名不尽相同。数据类型为 下面将选择我需要的具有两个列名的所有表 SELECT A.TABLE_NAME, A.COLUMN_NAME, B.COLUMN_NAME FROM all_tab_columns A JOIN all_tab_columns
SELECT A.TABLE_NAME, A.COLUMN_NAME, B.COLUMN_NAME
FROM all_tab_columns A
JOIN all_tab_columns B
ON A.TABLE_NAME = B.TABLE_NAME
AND B.DATA_TYPE = 'DATE'
AND A.COLUMN_NAME IN ('NAME', 'FULLNAME')
所以,现在我得到了我需要的表,它的数据类型是DATE,其中列名称和全名都存在
所以现在在2000个表中,我有300个符合我的标准。我想搜索日期为1984-01-01的JOHN表格,其中JOHN可以是全名或全名,1984-01-01可以是任何列名,即DTTM、BDAY、DATEFLD、DTFIELD等
我想要一个表名,这两个值在同一行中,没有别的
我已经看过这些类型的例子:
但问题不断。我错过了什么
DECLARE
match_count INTEGER;
v_search_string VARCHAR2 (11) := 'JOHN';
BEGIN
FOR t
IN (SELECT A.owner, A.table_name, A.column_name
FROM all_tab_columns A
JOIN all_tab_columns B
ON A.TABLE_NAME = B.TABLE_NAME
AND A.COLUMN_NAME IN ('NAME', 'FULLNAME')
AND B.DATA_TYPE = 'DATE'
AND A.TABLE_NAME LIKE 'DATA%')
LOOP
BEGIN
EXECUTE IMMEDIATE
'SELECT * FROM '
|| t.owner
|| '.'
|| t.table_name
|| ' WHERE '
|| t.column_name
|| ' = :1 '
INTO match_count
USING v_search_string;
IF match_count > 0
THEN
DBMS_OUTPUT.put_line (
t.table_name
);
END IF;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'Error encountered trying to read '
|| t.column_name
|| ' from '
|| t.owner
|| '.'
|| t.table_name);
END;
END LOOP;
END;
/
您可以尝试使用
all\u tab\u columns
中的select来构造where子句,并在动态where子句中查询相应的表
SET serveroutput ON
DECLARE
v_count INTEGER;
BEGIN
FOR r IN (SELECT a.table_name,
' WHERE '
|| LISTAGG(CASE data_type
WHEN 'DATE' THEN column_name
|| ' = DATE '
|| '''1984-01-01'''
ELSE column_name
|| ' = '
|| '''JOHN'''
END, ' or ')
WITHIN GROUP( ORDER BY column_name ) AS where_clause
FROM user_tab_columns a
WHERE column_name IN ( 'NAME', 'FULLNAME' )
OR ( data_type = 'DATE'
AND column_name IN ( 'DTTM', 'BDAY', 'DATEFLD',
'DTFIELD'
) )
GROUP BY table_name) LOOP
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '|| r.table_name||
r.where_clause
INTO
v_count;
IF v_count > 0 THEN
dbms_output.Put_line(r.table_name);
END IF;
END LOOP;
END;
/
请注意,我给您的是一个示例,它为您提供了一些想法,您可以构造它并调整隐式游标循环的查询(在r in()
)为了满足您的需要,可以使用和/或/JOIN
条件INTERSECT
操作符等,我这样做是为了从我的角度进行测试
编辑:另一个选项是蛮力方法,即使用动态where子句搜索数据库中的所有表,如果在表中找不到where子句中的列,则忽略异常
SET serveroutput ON
DECLARE
v_count NUMBER;
v_where_clause VARCHAR2(400) :=
' WHERE DTTM = DATE ''1984-01-01'' AND FULLNAME = ''JOHN''';
BEGIN
FOR r IN (SELECT owner,
table_name
FROM all_tables) LOOP
BEGIN
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '|| r.owner|| '.'||
r.table_name
||
v_where_clause INTO v_count;
IF v_count > 0 THEN
dbms_output.put_line(r.owner||'.'||r.table_name);
END IF;
EXCEPTION
WHEN OTHERS THEN
NULL; --It is ok in this case as you know why it fails.
END;
END LOOP;
END;
/
我对你的代码做了一些小的修改:
DECLARE
match_count INTEGER;
v_search_string VARCHAR2 (11) := 'JOHN';
v_search_date DATE := date '1984-01-01';
BEGIN
FOR t IN (
SELECT A.owner, A.table_name, A.column_name text_column_name, B.column_name date_column_name
FROM all_tab_columns A
JOIN all_tab_columns B
ON A.TABLE_NAME = B.TABLE_NAME
AND A.OWNER = B.OWNER
AND A.COLUMN_NAME IN ('NAME', 'FULLNAME')
AND B.DATA_TYPE = 'DATE'
AND A.TABLE_NAME LIKE 'DATA%'
) LOOP
BEGIN
EXECUTE IMMEDIATE
'SELECT count(*) FROM '
|| t.owner
|| '.'
|| t.table_name
|| ' WHERE '
|| t.text_column_name
|| ' = :1'
|| ' and '
|| t.date_column_name
|| ' = :2'
INTO match_count
USING v_search_string, v_search_date;
IF match_count > 0
THEN
DBMS_OUTPUT.put_line (
'Found! '||t.table_name
);
ELSE
DBMS_OUTPUT.put_line (
'No matches for '||t.table_name||'('||t.text_column_name||','||t.date_column_name||')'
);
END IF;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'Error encountered trying to read from '
|| t.owner
|| '.'
|| t.table_name);
END;
END LOOP;
END;
/
“我已经看了…但一直有问题”什么问题?我们不知道。我不知道如何在链接发布后搜索两个值。它只适用于一个值。。。如何搜索两个值?这就是我的问题……好吧,在WHERE子句中使用AND运算符,并调整语句的定义,使之在两种数据类型中循环。告诉我们你尝试过什么。编辑包括我走了多远。请也包括你收到的错误。这个先生,工作非常好-结果我在这里和那里漏掉了一点。谢谢你的帮助!