我想将表的内容与正则表达式模式和在过程中保存为变量的column_name进行比较。 Regexp_like 和变量 v_column_name、v_column_regexp 位于 if 语句中。
/* Formatted on 22/02/2024 08:28:07 (QP5 v5.401) */
CREATE OR REPLACE PROCEDURE EXTTBL_COLUMN_REGEX (
p_data_flow IN VARCHAR2,
p_exttable_name IN VARCHAR2)
AS
v_data_flow VARCHAR2 (50);
v_exttable_name VARCHAR2 (200);
v_column_name VARCHAR2 (100);
v_column_regexp VARCHAR2 (100);
v_row_rownum NUMBER;
BEGIN
v_data_flow := p_data_flow;
v_exttable_name := p_exttable_name;
FOR i
IN (SELECT column_name, t1.column_type, column_regexp
FROM T_DD_EXTTBL_COLUMN t1
INNER JOIN t_dd_column_regexp t2
ON t1.column_type = t2.column_type
WHERE data_flow = v_data_flow AND table_name = v_exttable_name)
LOOP
v_column_name := i.column_name;
v_column_regexp := i.column_regexp;
INSERT INTO T_LOG_EXTTBL_COLUMN (DATA_FLOW, EXTTABLE_NAME, LOG_TEXT)
VALUES ( v_data_flow, v_exttable_name, v_column_name || ' REGEXP Check starts with ' || v_column_regexp);
FOR r_row IN (SELECT v_column_name, ROWNUM FROM T_TEST_4)
LOOP
v_row_rownum := r_row.ROWNUM;
IF NOT REGEXP_LIKE (v_column_name, v_column_regexp)--v_column_name:='FIRST_DATE' with content as '20231100', v_column_regexp:='^\d{4}(0[1-9]|1[012])00$'
THEN
INSERT INTO T_LOG_EXTTBL_COLUMN (DATA_FLOW,
EXTTABLE_NAME,
LOG_TEXT,
LOG_TIME)
VALUES ( v_data_flow, v_exttable_name, 'In '|| v_row_rownum || ': ' || v_column_name, SYSDATE);
ELSE
INSERT INTO T_LOG_EXTTBL_COLUMN (DATA_FLOW,
EXTTABLE_NAME,
LOG_TEXT,
LOG_TIME)
VALUES ( v_data_flow, v_exttable_name, 'REGEXP_LIKE (' || v_column_name || ', ' || v_column_regexp || ') matched ', SYSDATE);
COMMIT;
END IF;
COMMIT;
END LOOP;
END LOOP;
END;
/
它在 if 语句中不匹配,即使我在 select 语句中使用 regexp_like 时得到匹配。
SELECT DISTINCT rownum, FIRST_DATE
FROM T_TEST_4
WHERE REGEXP_LIKE (FIRST_DATE, '^\d{4}(0[1-9]|1[012])00$')
1 20231100
2 20231100
3 20231100
4 20231100
您的查询
SELECT v_column_name, ROWNUM FROM T_TEST_4
将获取表中每一行的变量的字面值(即列name),而不是列value。
您可以在这个简化的演示中看到:
declare
v_column_name all_tab_columns.column_name%type := 'DUMMY';
begin
for r_row in (select v_column_name as col from dual)
loop
dbms_output.put_line(r_row.col);
end loop;
end;
/
dbms_output:
DUMMY
它显示列名称 DUMMY,而不是值 X。
如果您使用动态 SQL 游标循环,那么您将获得该值:
declare
v_column_name all_tab_columns.column_name%type := 'DUMMY';
v_cursor sys_refcursor;
v_value varchar2(4000);
begin
open v_cursor for 'select "' || v_column_name || '" from dual';
loop
fetch v_cursor into v_value;
exit when v_cursor%notfound;
dbms_output.put_line(v_value);
end loop;
end;
/
dbms_output:
X
您可以调整您的代码来完成同样的事情;为光标和结果添加变量声明:
v_cursor sys_refcursor;
v_column_value varchar2(4000);
v_rownum number;
并将循环更改为:
FOR r_row IN (SELECT v_column_name, ROWNUM FROM T_TEST_4)
LOOP
v_row_rownum := r_row.ROWNUM;
IF NOT REGEXP_LIKE (v_column_name, v_column_regexp)
...
到
OPEN v_cursor FOR 'SELECT "' || v_column_name || '", ROWNUM FROM T_TEST_4';
LOOP
FETCH v_cursor INTO v_column_value, v_row_rownum;
EXIT WHEN v_cursor%NOTFOUND;
IF NOT REGEXP_LIKE (v_column_value, v_column_regexp)
...
并且当您插入日志表时也可能将
v_column_name
更改为 v_column_value
。 (您可能不想在每次插入后都提交......)