如何在Oracle SQL

时间:2018-05-24 15:26:23

标签: sql plsql oracle11g dynamic-sql

我要做的是根据两个表之间的条件创建视图,并且我希望它遍历满足此条件的所有表。

我一直在做一些研究,我发现游标会对这类事情有所帮助,但我在第15行遇到了“超出范围”的光标。

DECLARE

  query_str  VARCHAR2(32000);
  CURSOR all_syn IS
    SELECT SYNONYM_NAME, TABLE_NAME
    FROM ALL_SYNONYMS
    WHERE SYNONYM_NAME LIKE 'S!_AG!_%' ESCAPE '!';
  CURSOR our_tables IS
    SELECT TABLE_NAME
    FROM   ALL_TABLES
    WHERE  TABLE_NAME LIKE 'AG!_%1' ESCAPE '!';

BEGIN

  query_str := 'CREATE OR REPLACE VIEW ' || LTRIM(all_syn.SYNONYM_NAME, 'S_') || 'AS
        SELECT TO_CHAR(itemnum) itemnum,
               TO_CHAR(keywordnum) keywordnum,
               TO_CHAR(keysetnum) keysetnum,
               MOD_BY_EMPLOYEE,
               MOD_BY_PROCESS,
               MOD_DATE_EMPLOYEE,
               MOD_DATE_PROCESS
        FROM   all_syn.SYNONYM_NAME,
               our_tables.TABLE_NAME
        WHERE  our_tables.TABLE_NAME = ' || LTRIM(all_syn.SYNONYM_NAME, 'S_');
  FOR v_rec IN all_syn LOOP
IF (v_rec.TABLE_NAME LIKE 'KEYXITEM%') THEN
 EXECUTE IMMEDIATE query_str;

    END IF;
  END LOOP;
END;

我这样做的原因是因为我公司的表格没有直接连接到某个第三方数据库链接,所以他们让我通过在受影响的表格的末尾添加1来更改表名,创建这些表的同义词使用DB链接,然后使用原始表名创建这些同义词的视图,以便它们现在具有DB链接并充当原始表,以便我们不必更改任何代码。我必须使用更改的表加入同义词表,因为我们添加了第三方表没有的一些属性。

如果有人有任何建议或意见,我们将不胜感激!我是新手使用动态sql和PL / SQL,所以请耐心等待。

编辑:

所以我改进了我的代码,我觉得我越来越接近我想要的结果,但是我得到了这个奇怪的错误:

第28行,第52栏: PLS-00357:在此上下文中不允许使用表,视图或序列引用“ALL_TABLES.TABLE_NAME”

当我在查询中声明它时,这对我没有意义。

BEGIN
  FOR v_rec IN all_syn LOOP
    IF (v_rec.TABLE_NAME LIKE 'KEYXITEM%') THEN
      query_str := 'CREATE OR REPLACE VIEW ' || LTRIM(v_rec.SYNONYM_NAME, 'S_') || ' AS
          SELECT itemnum AS item_num,
                 keywordnum AS key_word_num,
                 keysetnum AS key_set_num,
                 MOD_BY_EMPLOYEE,
                 MOD_BY_PROCESS,
                 MOD_DATE_EMPLOYEE,
                 MOD_DATE_PROCESS,
          FROM   (    SELECT TABLE_NAME
                      FROM   ALL_TABLES
                      WHERE  TABLE_NAME LIKE ' || '''AG!_%1''' || ' ESCAPE ' || '''!''' || '
                         AND ' || RTRIM(ALL_TABLES.TABLE_NAME, '1') ||' = ' || LTRIM(v_rec.SYNONYM_NAME, 'S_') || ') our_tables,   
                 ' || v_rec.SYNONYM_NAME;
     -- EXECUTE IMMEDIATE query_str;
    END IF;
              dbms_output.put_line(query_str);
  END LOOP;
END;

1 个答案:

答案 0 :(得分:1)

你不能像那样引用光标。将query_str创建移动到FOR LOOP中并引用记录变量。

编辑:我试图修复FROM / WHERE子句,但你可能在那里错过了一个连接条件。

DECLARE
  query_str  VARCHAR2(32000);
  CURSOR all_syn IS
    SELECT SYNONYM_NAME, TABLE_NAME
    FROM ALL_SYNONYMS
    WHERE SYNONYM_NAME LIKE 'S!_AG!_%' ESCAPE '!';
  CURSOR our_tables IS
    SELECT TABLE_NAME
    FROM   ALL_TABLES
    WHERE  TABLE_NAME LIKE 'AG!_%1' ESCAPE '!';

BEGIN
  FOR v_rec IN all_syn LOOP
    IF (v_rec.TABLE_NAME LIKE 'KEYXITEM%') THEN
      query_str := 'CREATE OR REPLACE VIEW ' || LTRIM(v_rec.SYNONYM_NAME, 'S_') || 'AS
          SELECT TO_CHAR(itemnum) itemnum,
                 TO_CHAR(keywordnum) keywordnum,
                 TO_CHAR(keysetnum) keysetnum,
                 MOD_BY_EMPLOYEE,
                 MOD_BY_PROCESS,
                 MOD_DATE_EMPLOYEE,
                 MOD_DATE_PROCESS
          FROM   ' || v_rec.SYNONYM_NAME || ',
                 ' || v_rec.TABLE_NAME || '
          WHERE  ' || v_rec.TABLE_NAME = ' || LTRIM(v_rec.SYNONYM_NAME, 'S_');
      EXECUTE IMMEDIATE query_str;
    END IF;
  END LOOP;
END;