我需要帮助构建与以下查询相关的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;
答案 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