搜索 table 中的所有 varchar 列并输出该行
Search all varchar columns in table and output the row
我需要有关构建与以下查询相关的 PL/SQL 块的帮助:
SELECT <PRIMARY_KEY_COLUMN>, <VARCHAR_COLUMN> FROM TABLENAME WHERE REGEXP_LIKE(VARCHAR_COLUMN, UNISTR('[\D800-\DFFF]'));
以上查询将给出与范围内提及的所有 UTF8 字节相关的输出。
我会请你们帮我修改上面的查询,这样我就可以 运行 它在所有 VARCHAR/CLOB 列table 并得到这样的输出:
ColumnName Value Primary_key_Column
-----------------------------------------------------------------------
Col1 v1 123
Col1 v2 124
.
.
Col2 v1 167
Col2 v2 123
.
.
欢迎评论并分享您的意见。
更新1:
我能够根据收到的评论和其中一篇帖子构建以下块,但它仍然需要编辑:
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;
这是一个静态解决方案(它不需要任何 PL/SQL 代码,但需要预先了解 table 和列名,并知道必须包含哪些列)。它还假定所有 "text" 列都是 VARCHAR2
;正如我在评论中所解释的那样,您不应期望能够在输出的同一列中 return VARCHAR2 和 CLOB 值。 (也许,如果你必须一次性完成所有事情,你需要在输出中包含几列:column_name 和 column_type,如 VARCHAR2 与 CLOB,然后是两个值列,一个用于 VARCHAR2 列原始 table 和另一个用于 CLOB 值。)
您可以使用与 PL/SQL 代码类似的东西使其动态化;不推荐。
所以,无论如何,这是静态解决方案。它在 SCOTT 模式中使用 EMP table。 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
我需要有关构建与以下查询相关的 PL/SQL 块的帮助:
SELECT <PRIMARY_KEY_COLUMN>, <VARCHAR_COLUMN> FROM TABLENAME WHERE REGEXP_LIKE(VARCHAR_COLUMN, UNISTR('[\D800-\DFFF]'));
以上查询将给出与范围内提及的所有 UTF8 字节相关的输出。
我会请你们帮我修改上面的查询,这样我就可以 运行 它在所有 VARCHAR/CLOB 列table 并得到这样的输出:
ColumnName Value Primary_key_Column
-----------------------------------------------------------------------
Col1 v1 123
Col1 v2 124
.
.
Col2 v1 167
Col2 v2 123
.
.
欢迎评论并分享您的意见。
更新1:
我能够根据收到的评论和其中一篇帖子构建以下块,但它仍然需要编辑:
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;
这是一个静态解决方案(它不需要任何 PL/SQL 代码,但需要预先了解 table 和列名,并知道必须包含哪些列)。它还假定所有 "text" 列都是 VARCHAR2
;正如我在评论中所解释的那样,您不应期望能够在输出的同一列中 return VARCHAR2 和 CLOB 值。 (也许,如果你必须一次性完成所有事情,你需要在输出中包含几列:column_name 和 column_type,如 VARCHAR2 与 CLOB,然后是两个值列,一个用于 VARCHAR2 列原始 table 和另一个用于 CLOB 值。)
您可以使用与 PL/SQL 代码类似的东西使其动态化;不推荐。
所以,无论如何,这是静态解决方案。它在 SCOTT 模式中使用 EMP table。 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