首页 > 解决方案 > 数据未插入到目标表

问题描述

我在 Oracle 中有以下 PL-SQL 代码块:

DECLARE  TAB VARCHAR(100);
         COL VARCHAR(100);

CURSOR C_COLS IS
          select DISTINCT table_name, column_name
          from all_tab_columns 
          where OWNER = 'MyDB' AND DATA_TYPE LIKE '%VARCHAR%';
BEGIN
    OPEN C_COLS;
    LOOP
      FETCH C_COLS INTO TAB, COL;
      EXIT WHEN C_COLS%notfound; 
        INSERT INTO TargetTable (TABLE_NAME, COLUMN_NAME, COLUMN_VALUE)
        SELECT  DISTINCT   TAB, 
                           COL,
                           (SELECT COL FROM TAB)
FROM TAB
WHERE REGEXP_LIKE(COL, '([ABCDEFGHIJKLMNOPQRSTUVWXYZ])\d\d\d\d\d\d([ABCDEFGHIJKLMNOPQRSTUVWXYZ])', 'ix');
     END LOOP;
     CLOSE C_COLS;
END;

这个想法是确定我相当大的数据库中的哪些表包含某种数据模式并找到它们。

所以我想返回三列:TableName、ColumnName、ColumnName 的值。

以上运行但不返回任何数据,我不明白为什么。游标中的查询返回结果,如果我将表值硬编码到包含我的正则表达式的简单选择语句中,我会得到结果。我只想要一个包含我期望的数千个结果的结果集。

可能是(SELECT COL FROM TAB)我用来动态查找 column_value 的吗?我不确定我是否可以这样表达。

标签: oracleplsqlcursor

解决方案


如果您想动态选择列,您可能希望尝试动态 SQL

DECLARE  
  w_sql VARCHAR2(32767);
BEGIN
  DBMS_OUTPUT.enable(32767);
  FOR s_cols IN (
    select DISTINCT 
           table_name
         , column_name
      from all_tab_columns 
     where owner = 'MyDB' 
       AND data_type LIKE '%VARCHAR%'
  )
  LOOP
    w_sql := q'!
      INSERT 
        INTO TargetTable (TABLE_NAME, COLUMN_NAME, COLUMN_VALUE)
      SELECT DISTINCT 
             ':TAB'
           , ':COL'
           , :COL
        FROM :TAB
       WHERE REGEXP_LIKE(:COL, '([ABCDEFGHIJKLMNOPQRSTUVWXYZ])\d\d\d\d\d\d([ABCDEFGHIJKLMNOPQRSTUVWXYZ])', 'ix')
    !';
    w_sql := REPLACE(w_sql, ':TAB', s_cols.table_name);
    w_sql := REPLACE(w_sql, ':COL', s_cols.column_name);
    EXECUTE IMMEDIATE w_sql;
  END LOOP;
  COMMIT;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.put_line('Error for SQL :'|| w_sql ||'; error is :'|| SQLERRM);
END;

推荐阅读