【问题标题】:Search all varchar columns in table and output the row搜索表中所有 varchar 列并输出该行
【发布时间】:2017-10-09 02:36:03
【问题描述】:

在构建与以下查询相关的 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
.
.

请查看并分享您的 cmets。

更新1:

我能够根据收到的 cmets 和其中一篇帖子构建以下块,但它仍然需要编辑:

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;

【问题讨论】:

  • @KaushikNayak :我尝试了以下帖子中提到的查询:[link]stackoverflow.com/questions/208493/… [link]stackoverflow.com/questions/12921792/… 但是在我正在做的基于模式的搜索方面遇到了障碍。因此,发布了问题
  • @JSapkota :所以关于我在问题中提到的select 查询,它输出与我提供的模式匹配的 primary_key_column_value,varchar_column。所以我在这里尝试构建的是一个查询,它将扫描特定表中的所有 varchars/clob 列,并给出我提到的输出。请帮忙。
  • 只需替换 ` ' WHERE '||t.column_name||' = :1'....USING` 与 WHERE REGEXP_LIKE( '||t.column_name||' ,:1')USING UNISTR('[\D800-\DFFF]')
  • @KaushikNayak 但这给了我计数。很抱歉我很笨,但你能告诉我如何修改选择查询以获得我需要的输出格式吗?
  • 需要在select中选择主键列和匹配的列名,而不是count。然后按照你喜欢的顺序显示。

标签: oracle plsql database-table


【解决方案1】:

这是一个静态解决方案(它不需要任何 PL/SQL 代码,但需要事先了解表名和列名,并知道必须包含哪些列)。它还假设所有“文本”列都是VARCHAR2;正如我在评论中解释的那样,您不应该期望能够在输出的同一列中返回 VARCHAR2 和 CLOB 值。 (也许,如果您必须一次性完成所有操作,您需要在输出中包含几列:column_name 和 column_type,如 VARCHAR2 与 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

【讨论】:

  • 这真的很有帮助。您能帮忙将这个SELECT REGEXP_SUBSTR(str, UNISTR('[\FFFF-\DBFF\DFFF]')) AS substr, primary_key FROM (SELECT VARCHAR_COLUMN str, PRIMARY_COLUMN primary_key FROM CS_ACTIONS) where REGEXP_SUBSTR(str, UNISTR('[\FFFF-\DBFF\DFFF]')) is not null; 转换为您提到的最终选择查询吗?再次感谢一吨!
猜你喜欢
  • 2017-06-20
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
  • 2016-06-15
  • 2016-07-18
  • 1970-01-01
  • 2021-02-28
  • 1970-01-01
相关资源
最近更新 更多