Можно ли в любом случае запускать множественные процедуры вплотную в PL / SQL, чтобы таблица создавалась, а затем заполнялась, как структурировано в моем коде? - PullRequest
1 голос
/ 23 апреля 2020

Я работаю с Oracle SQL Разработчиком и пытаюсь заставить работать приведенный ниже код, но просто не могу понять это. Я пробовал несколько различных методов, включая реализацию циклов for, немедленного выполнения, планирования и перекомпиляции.

BEGIN
  ORDER_STATUS_1_DROP_TABLE;    -- If the table exist, drop it
  ORDER_STATUS_2_CREATE_TABLE;  -- Create the table
  GRANT_NEWANALYTICS;           -- Grant users select access
  ORDER_STATUS_3_SCRIPT;        -- Run script to insert data into table
END;

Код пытается сделать следующее:

Процедура 1: Удалить, если существует, в противном случае пропустите. Я не хочу видеть никаких предупреждений о том, что таблица не существует, если эта процедура выполняется, когда таблицы нет. Эта процедура сама по себе работает как задумано.

create or replace PROCEDURE ORDER_STATUS_1_DROP_TABLE IS 
    table_does_not_exist EXCEPTION;
    PRAGMA EXCEPTION_INIT(table_does_not_exist, -942);
  BEGIN
    EXECUTE IMMEDIATE 'DROP TABLE <Table Name>';
  EXCEPTION
    WHEN table_does_not_exist then
    dbms_output.put_line( 'table dose not exist');
  END ORDER_STATUS_1_DROP_TABLE;

Процедура 2: После удаления таблицы эта процедура воссоздает ее с правильным значением. Я не хочу видеть никаких ошибок для "этой таблицы уже существует", и именно поэтому, частично, процедура 1 существует. Само по себе это работает как задумано.

create or replace PROCEDURE ORDER_STATUS_2_CREATE_TABLE IS
    v_sql LONG;
  BEGIN
    v_sql:= 'create table <Table Name>
      (<parameters>)';
  EXECUTE IMMEDIATE v_sql;
  END ORDER_STATUS_2_CREATE_TABLE;

Процедура 3: Это просто дает пользователям выбор доступа к таблице, созданной в последней процедуре. Эта процедура работает так, как и было задумано.

create or replace PROCEDURE GRANT_NEWANALYTICS IS 
  BEGIN
    EXECUTE IMMEDIATE
      'GRANT SELECT ON <Table Name> TO <UserID>';
  END;

Процедура 4: Это сложный запрос. Это вставка «Выбрать все из» (присоединение таблицы к нескольким другим таблицам на основе полей и условий и т. Д. c). После запуска процедур 1-3 эта процедура сама по себе не вызывает проблем, но сама по себе.

create or replace PROCEDURE ORDER_STATUS_3_SCRIPT IS 

  BEGIN
    DELETE FROM <Table Name>;
    INSERT INTO <Table Name>
    SELECT * FROM(<Multiple Table Joins>);
  END ORDER_STATUS_3_SCRIPT;

Когда я запускаю процедуры следующим образом:

  BEGIN
   ORDER_STATUS_1_DROP_TABLE;    -- If the table exist, drop it
   ORDER_STATUS_2_CREATE_TABLE;  -- Create the table
   GRANT_NEWANALYTICS;           -- Grant users select access
   ORDER_STATUS_3_SCRIPT;        -- Run script to insert data into table
  END;

Я получаю следующий отчет об ошибке:

Error report -
ORA-04068: existing state of packages has been discarded
ORA-04065: not executed, altered or dropped stored procedure "<user>.ORDER_STATUS_3_SCRIPT"
ORA-06508: PL/SQL: could not find program unit being called: "<user>.ORDER_STATUS_3_SCRIPT"
ORA-06512: at line 5
04068. 00000 -  "existing state of packages%s%s%s has been discarded"
*Cause:    One of errors 4060 - 4067 when attempt to execute a stored procedure.
*Action:   Try again after proper re-initialization of any application's state.

Теперь, если я запускаю их отдельно, это работает. Так что, если я сначала запустите это:

 BEGIN
  ORDER_STATUS_1_DROP_TABLE;    -- If the table exist, drop it
  ORDER_STATUS_2_CREATE_TABLE;  -- Create the table
  GRANT_NEWANALYTICS;           -- Grant users select access
END;
<OUTPUT> PL/SQL procedure successfully completed.

А потом это:

BEGIN
ORDER_STATUS_3_SCRIPT;        -- Run script to insert data into table
END;
<OUTPUT> <Query runs>

У меня нет проблем. Я хочу запустить этот набор процедур одним махом и мог бы использовать некоторую помощь по идее. У кого-нибудь есть идеи?

1 Ответ

2 голосов
/ 23 апреля 2020

Если вы хотите запустить все эти процедуры как часть одного блока PL / SQL, тогда каждая ссылка на вашу таблицу должна быть через Dynami c SQL. Таким образом, ORDER_STATUS_3_SCRIPT необходимо будет использовать Dynami c SQL для построения оператора (-ов) вставки для заполнения таблицы, а не с использованием простого состояния c SQL. Это очевидно возможно, но это увеличивает сложность сценария. Потенциально существенно.

Имея два PL / SQL блока, которые вы продемонстрировали, кажется, намного проще.

...