【发布时间】:2021-02-14 01:56:24
【问题描述】:
大家好,我正在尝试从 oracle db 11g 获取某些电子邮件模式,我使用了以下查询
不幸的是,我必须扫描完整的模式才能获取值 (@pqr.de),它存在于它所在的列和表中,理想情况下,此活动是列出非活动电子邮件地址(非活动eamil地址我需要在其他系统中单独检查而不是通过查询)
查询
--desc dba_tab_cols
SET SERVEROUTPUT ON 100000
DECLARE
l_sql CLOB;
l_where CLOB;
l_result INT;
BEGIN
FOR i IN (SELECT table_name,
column_name,
Row_number()
over (
PARTITION BY table_name
ORDER BY column_name ) AS seq,
Count(*)
over (
PARTITION BY table_name ) AS cnt
FROM dba_tab_columns
WHERE data_type IN ( 'CHAR', 'CLOB', 'NCHAR', 'NVARCHAR2',
'VARCHAR2'
)) LOOP
IF i.seq = 1 THEN
l_sql := 'select '
||Chr(10);
l_where := 'where '
||Chr(10);
END IF;
l_sql := l_sql
|| ' max(case when '
||i.column_name
||' like ''%@pqr.de%'' then '
||Power(2, i.seq - 1)
||' else 0 end)+'
||Chr(10);
l_where := l_where
|| ' '
||i.column_name
||' is not null or'
||Chr(10);
IF i.seq = i.cnt THEN
l_sql := Rtrim(l_sql, '+'
||Chr(10))
||Chr(10)
||'from '
||i.table_name
||Chr(10)
||Substr(l_where, 1, Length(l_where) - 4);
dbms_output.Put_line('---------------------------------------');
dbms_output.Put_line(l_sql);
EXECUTE IMMEDIATE l_sql INTO l_result;
IF l_result > 0 THEN
dbms_output.Put_line('Found!!! l_result='
||l_result);
END IF;
END IF;
END LOOP;
END;
/
我遇到了错误
错误报告 -
ORA-00936: missing expression
ORA-06512: at line 54
00936. 00000 - "missing expression"
*Cause:
*Action:
如何解决错误,因为我正在尝试从上述查询中检索表列表
测试查询 - 在第 60 行失败
SET SERVEROUTPUT ON 100000
DECLARE
l_sql CLOB;
l_where CLOB;
l_result INT;
BEGIN
FOR i IN (SELECT owner,
table_name,
column_name,
Row_number()
over (
PARTITION BY table_name
ORDER BY column_name ) AS seq,
Count(*)
over (
PARTITION BY table_name ) AS cnt
FROM all_tab_columns
--WHERE owner not in ('LIST_OF_SCHEMAS') -- list relevant schemas
AND data_type IN ( 'CHAR', 'CLOB', 'NCHAR', 'NVARCHAR2',
'VARCHAR2'
)) LOOP
IF i.seq = 1 THEN
l_sql := 'select '
||Chr(10);
l_where := 'where '
||Chr(10);
END IF;
l_sql := l_sql
|| ' max(case when "'
||i.column_name
||'" like ''%@pqr.de%'' then '
||Power(2, i.seq - 1)
||' else 0 end)+'
||Chr(10);
l_where := l_where
|| ' "'
||i.column_name
||'" is not null or'
||Chr(10);
IF i.seq = i.cnt THEN
l_sql := Rtrim(l_sql, '+'
||Chr(10))
||Chr(10)
||'from "'
||i.owner
||'"."'
||i.table_name
||'"'
||Chr(10)
||Substr(l_where, 1, Length(l_where) - 4);
dbms_output.Put_line('---------------------------------------');
---dbms_output.Put_line(l_sql);
dbms_output.Put_line(dbms_lob.substr(l_sql, 4000, 1));
EXECUTE IMMEDIATE l_sql INTO l_result;
IF l_result > 0 THEN
dbms_output.Put_line('Found!!! l_result='
||l_result);
END IF;
END IF;
END LOOP;
END;
错误报告 -
Error report -
ORA-06502: PL/SQL: numeric or value error: number precision too large
ORA-06512: at line 61
06502. 00000 - "PL/SQL: numeric or value error%s"
*Cause:
*Action:
【问题讨论】:
-
据我计算,根据您问题中的代码,第 54 行是:
EXECUTE IMMEDIATE l_sql INTO l_result;这意味着l_sql包含无效的 SQL。在该行之前,您在该行中打印l_sql的值:dbms_output.Put_line(l_sql);。请edit您的问题并发布l_sql的值,其中包含导致错误ORA-00936的SQL。 -
您有带引号标识符的表吗?我怀疑其中一个构造查询看到了它不喜欢的列名。最后打印的
l_sql应该告诉你哪个?顺便说一句,您正在查看整个数据库,而不是特定的模式;您可能想在光标上添加一个owner过滤器,并可能查看all_而不是dba_视图。 -
@AlexPoole 基本上我正在尝试扫描整个 dwh 以识别电子邮件行存在的表、列 (@pqr.de),您能否在查询中编辑它必须更正的地方?
-
我明白了,但是您正在查看内部表(例如 SYS 和 SYSTEM 模式)以及您感兴趣的那些,以及视图和表;通过查询
dba_视图,您可能会选择您无权查询的表。您可以通过修改游标查询来更有选择性。您得到的错误是另一回事;就像我说的,可能是一个带引号的标识符,来自使用保留字的表或列名。请编辑您的问题以包含它打印的最后一个l_sql值。 -
我不明白这整件事的前提。 (直言不讳:它暗示要么试图做错事,要么严重无能,或者试图隐藏自己的错误,等等。)你为什么要在“驾驶执照号码”之类的列中搜索电子邮件地址?在所有表中的所有(字符串)列中搜索 whatever 绝不是合理的做法(除非您正在寻找病毒签名等)。