Как создать представление в цикле FOR в Oracle SQL - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь создать представления, основанные на условии между двумя таблицами, и я хочу, чтобы он просматривал все таблицы, соответствующие этому условию.

Я провел некоторое исследование и обнаружил, что курсоры будут полезны для такого рода вещей, но я столкнулся с «курсором вне области видимости» в строке 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 в конце затронутых таблиц,создавая синонимы для этих таблиц с помощью ссылки на БД, а затем создавайте представления этих синонимов с исходным именем таблицы, чтобы они теперь имели ссылку на БД и действовали как исходная таблица, чтобы нам не пришлось изменять какой-либо код.Я должен объединить таблицы синонимов с измененными таблицами, потому что мы добавили некоторые атрибуты, которых нет у сторонних таблиц.

Если у кого-либо есть какие-либо предложения или советы, это будет с благодарностью!Я новичок в использовании динамических 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 голосов
/ 24 мая 2018

Вы не можете ссылаться на курсор таким образом.Переместите создание query_str в FOR LOOP и создайте ссылку на переменную record.

EDIT: я пытался исправить предложение 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;
...