Sql 如何从oracle数据库中获取电子邮件地址
大家好,我正在尝试从oracle db 11g获取某些电子邮件模式,我使用了以下查询 不幸的是,我必须扫描完整的模式,以便获取值(@pqr.de),该值存在于它所在的列和表中,理想情况下,此活动是列出非活动电子邮件地址(非活动eamil地址,我需要在其他系统中单独检查,而不是通过查询) 查询Sql 如何从oracle数据库中获取电子邮件地址,sql,oracle,plsql,Sql,Oracle,Plsql,大家好,我正在尝试从oracle db 11g获取某些电子邮件模式,我使用了以下查询 不幸的是,我必须扫描完整的模式,以便获取值(@pqr.de),该值存在于它所在的列和表中,理想情况下,此活动是列出非活动电子邮件地址(非活动eamil地址,我需要在其他系统中单独检查,而不是通过查询) 查询 --desc dba_tab_cols SET SERVEROUTPUT ON 100000 DECLARE l_sql CLOB; l_where CLOB; l_r
--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:
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:
ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 19270, maximum: 4000)
ORA-06512: at line 60
如何解决此错误,因为我正在尝试从上述查询中检索表列表
测试查询-第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;
错误报告-
ORA-00936: missing expression
ORA-06512: at line 54
00936. 00000 - "missing expression"
*Cause:
*Action:
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:
ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 19270, maximum: 4000)
ORA-06512: at line 60
您的方法基本上是有效的(尽管有更简单的方法,如果您确实必须这样做的话;例如,有一些替代方法),因此您在执行特定的
l_sql
值时遇到的错误表明该特定构造存在问题。一个可能的罪魁祸首是表名或列名,它是一个保留字,这会使解析器感到困惑。您可能也会遇到带引号的标识符的问题,并且您正在所有模式(包括SYS等内部模式)中查找表,但没有指定每个表的所有者
通过在游标和构造语句中添加双引号和所有者,可以避免这些问题:
...
-- add owner to cursor
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
-- possibly query all_ instead of dba_
FROM all_tab_columns
-- limit to schema you're interested in
WHERE owner in (USER) -- list relevant schemas
AND data_type IN ( 'CHAR', 'CLOB', 'NCHAR', 'NVARCHAR2',
'VARCHAR2'
)) LOOP
...
l_sql := l_sql
-- add double-quotes around column name
|| ' max(case when "'
||i.column_name
||'" like ''%@pqr.de%'' then '
||Power(2, i.seq - 1)
||' else 0 end)+'
||Chr(10);
l_where := l_where
-- add double-quotes around column name
|| ' "'
||i.column_name
||'" is not null or'
||Chr(10);
IF i.seq = i.cnt THEN
l_sql := Rtrim(l_sql, '+'
||Chr(10))
||Chr(10)
-- add double-quotes around table name, and prefix with owner, also quoted (just in case!)
||'from "'
||i.owner
||'"."'
||i.table_name
||'"'
||Chr(10)
||Substr(l_where, 1, Length(l_where) - 4);
...
我已经测试了以下错误 错误报告-
ORA-00936: missing expression
ORA-06512: at line 54
00936. 00000 - "missing expression"
*Cause:
*Action:
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:
ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 19270, maximum: 4000)
ORA-06512: at line 60
查询应该可以使用CLOB值,因此我怀疑第60行现在是输出行,而l_sql
本身太大了;在这种情况下,您可以将其更改为:
dbms_output.Put_line(dbms_lob.substr(l_sql, 4000, 1));
错误报告-
ORA-00936: missing expression
ORA-06512: at line 54
00936. 00000 - "missing expression"
*Cause:
*Action:
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:
ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 19270, maximum: 4000)
ORA-06512: at line 60
ORA-06502:PL/SQL:数字或值错误:数字精度太高
ORA-06512:第61行
这可能是当
i.seq
达到128时power(2127)
对于int
结果变量来说太大了。如果我读对了,这意味着你有一个包含128个文本列的表?不知道这是什么意思。据我统计,根据您问题中的代码,第54行是:在l\u结果中执行立即l\u sql
这意味着l_sql
包含无效的sql。紧靠该行之前,您在此行中打印l\u sql
的值:dbms\u output.Put\u line(l\u sql)代码>。请回答您的问题,并发布包含导致错误ORA-00936的sql的l_sql
值。是否有带引号的标识符的表?我怀疑其中一个构造的查询看到了它不喜欢的列名。最后一次打印的l_sql
应该会显示哪个?顺便说一句,您查看的是整个数据库,而不是特定的模式;您可能想在光标上添加一个所有者
过滤器,并可能查看所有
而不是dba
视图。@AlexPoole基本上我正试图扫描整个dwh,以识别存在电子邮件行的表、列(@pqr.de),您能在查询中编辑它必须更正的位置吗?我明白了,但是您要查看的是内部表(例如SYS和系统模式)以及您感兴趣的表,还包括视图和表;通过查询dba\uu
视图,您可能会选择您没有查询权限的表。通过修改光标查询,您可以更具选择性。你所犯的错误是另一回事;就像我说的,可能是一个带引号的标识符,来自使用保留字的表或列名。请编辑您的问题,将最后打印的l\U sql
值包括在内。我不理解整件事的前提。(直截了当地说:这意味着要么是试图做错事,要么是严重的无能,要么是试图隐藏自己的错误,等等)你为什么要在“驾照号码”这样的栏中搜索电子邮件地址?搜索所有表中的所有(字符串)列以查找任何不合理的操作(除非您可能正在查找病毒签名等)。谢谢,我将测试查询,但没有几个问题1)使用dba_tab_cols与所有_tab_columns有什么区别2)——在列名周围添加双引号,我感兴趣的是搜索values@pqr.de,这样列可以是任何东西,也许我被误解了3)我想我也可以排除一些模式,比如SYS@rakesh-1)dba\uu
视图显示整个数据库的值,包括您可能无法访问的内容`所有视图都排除了您无法访问的内容。2) 添加双引号不会影响您搜索的表和列,它只会停止使用带引号的标识符(例如,大小写混合,或使用保留字)创建的导致问题的任何表和列。通常它们得到相同的结果,例如select*from dual
和select*from“dual”
。非常感谢你的解释,让我试着用我测试过的很少的模式进行测试,结果如下error@rakesh-最好将错误消息(不包括原因/操作部分)放在注释中。但我不知道你为什么会看到这些。代码中的第60行是什么?哦这是放线
?