Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何从oracle数据库中获取电子邮件地址_Sql_Oracle_Plsql - Fatal编程技术网

Sql 如何从oracle数据库中获取电子邮件地址

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

大家好,我正在尝试从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:
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行是什么?哦这是
放线