搜索表中的所有varchar列并输出该行

时间:2017-10-09 02:36:04

标签: oracle plsql database-table

我需要帮助构建与以下查询相关的PL / SQL块:

SELECT <PRIMARY_KEY_COLUMN>, <VARCHAR_COLUMN> FROM TABLENAME WHERE REGEXP_LIKE(VARCHAR_COLUMN, UNISTR('[\D800-\DFFF]'));

上述查询将给出与该范围中提到的所有UTF8字节相关的输出。

我会请求你们帮我修改上面的查询,这样我就可以在表中的所有 VARCHAR / CLOB 列上运行它并获得如下输出:

ColumnName                   Value                 Primary_key_Column
-----------------------------------------------------------------------
Col1                         v1                     123
Col1                         v2                     124
.
.
Col2                         v1                     167
Col2                         v2                     123
.
.

请审核并分享您的意见。

UPDATE1:

我能够从我收到的评论和其中一篇帖子中构建以下块,但仍需要编辑:

set serveroutput on;
DECLARE
  match_count integer;
  v_search_string varchar2(4000) := 'shazamTemplateId';
BEGIN  
  FOR t IN (SELECT owner, table_name, column_name FROM all_tab_columns WHERE data_type in ('CHAR', 'VARCHAR2', 'NCHAR', 'NVARCHAR2', 'CLOB', 'NCLOB') AND table_name = 'DECORATION_FIELDS') 
  LOOP   
    BEGIN
      EXECUTE IMMEDIATE    
          'SELECT COUNT(*) FROM ' || t.owner || '.' || t.table_name || ' WHERE REGEXP_LIKE( '||t.column_name||' = :1)'
          INTO match_count
          USING UNISTR('[\D800-\DFFF]');
      IF match_count > 0 THEN 
        dbms_output.put_line( t.owner || '.' || t.table_name ||' '||t.column_name||' '||match_count );
      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;

1 个答案:

答案 0 :(得分:0)

这是一个静态解决方案(它不需要任何PL / SQL代码,但它需要事先了解表和列名,并知道必须包含哪些列)。它还假设所有&#34;文本&#34;列是VARCHAR2;正如我在评论中解释的那样,您不应该期望能够在输出的同一列中返回VARCHAR2和CLOB值。 (也许,如果必须一次性完成所有操作,则输出中需要多个列:column_name,还有column_type,如VARCHAR2 vs CLOB,然后是两个值列,一个用于原始表中的VARCHAR2列,另一个用于CLOB值。)

您可以使用与PL / SQL代码类似的东西来使其动态化;我不推荐它。

所以,无论如何,这是静态解决方案。它使用SCOTT模式中的EMP表。 PK是EMPNO(NUMBER数据类型),有两个VARCHAR2列,ENAME和JOB。 EMP看起来像这样:

select * from emp;

EMPNO ENAME      JOB         MGR HIREDATE              SAL  COMM     DEPTNO
----- ---------- --------- ----- ------------------- ----- ----- ----------
 7369 SMITH      CLERK      7902 1980-12-17 00:00:00   800               20
 7499 ALLEN      SALESMAN   7698 1981-02-20 00:00:00  1600   300         30
 7521 WARD       SALESMAN   7698 1981-02-22 00:00:00  1250   500         30
 7566 JONES      MANAGER    7839 1981-04-02 00:00:00  2975               20
 7654 MARTIN     SALESMAN   7698 1981-09-28 00:00:00  1250  1400         30
 7698 BLAKE      MANAGER    7839 1981-05-01 00:00:00  2850               30
 7782 CLARK      MANAGER    7839 1981-06-09 00:00:00  2450               10
 7788 SCOTT      ANALYST    7566 1987-04-19 00:00:00  3000               20
 7839 KING       PRESIDENT       1981-11-17 00:00:00  5000               10
 7844 TURNER     SALESMAN   7698 1981-09-08 00:00:00  1500     0         30
 7876 ADAMS      CLERK      7788 1987-05-23 00:00:00  1100               20
 7900 JAMES      CLERK      7698 1981-12-03 00:00:00   950               30
 7902 FORD       ANALYST    7566 1981-12-03 00:00:00  3000               20
 7934 MILLER     CLERK      7782 1982-01-23 00:00:00  1300               10

解决问题的查询:(查询搜索包含从V到Z的字符的值;根据您的需要调整)

select   col_name, val, empno
from     emp
unpivot  ( val for col_name in (ename as 'ENAME', job as 'JOB') )
where    regexp_like( val, '[V-Z]' )
order by col_name, empno -- If needed
;

COL_NAME VAL        EMPNO
-------- ---------- -----
ENAME    WARD        7521
JOB      ANALYST     7788
JOB      ANALYST     7902