是否可以使用regexp_like中变量的内容作为Oracle中的源列

问题描述 投票:0回答:1

我想将表的内容与正则表达式模式和在过程中保存为变量的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
oracle if-statement regexp-like
1个回答
0
投票

您的查询

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
。 (您可能不想在每次插入后都提交......)

© www.soinside.com 2019 - 2024. All rights reserved.