Присвойте значение переменной и вызовите несколько команд - PullRequest
0 голосов
/ 22 мая 2019

Мне нужно присвоить значение переменной из выходных данных select запроса и вызвать переменную в командах sql

Например, для: я получаю PDB_NAME из v $ pdbs и присваиваю значение v_pdb. Я хочу использовать v_pdb в несколькихsql команды для запуска с PDB

Я пытался присвоить значение из запроса SELECT для v_pdb и вызвать v_pdb в 'alter session set container = v_pdb' ;, это похоже на работу, но я получаю ORA-00922: отсутствуетили ошибка неверной опции

set serveroutput on;
declare
v_sql varchar2(80);
v_pdb varchar2(30);
BEGIN
  FOR pdb IN (select name from v$pdbs where con_id=3 and OPEN_MODE='READ WRITE') 
  LOOP
    v_sql := 'alter session set container='||pdb.name;
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    --execute immediate 'alter session set container='||pdb.name||';';
    execute immediate v_sql;
    --v_sql := 'show con_name';
    --execute immediate 'show con_name';
    --execute immediate v_sql;
    v_sql := 'create tablespace APPDATA datafile '+DATA' size 1G autoextend on next 100M maxsize 5G ENCRYPTION USING 'AES256' DEFAULT STORAGE (ENCRYPT)';
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    execute immediate v_sql;
    v_sql := 'drop user bigschema cascade';
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    --execute immediate 'drop user bigschema cascade'; 
    execute immediate v_sql;
    v_sql := 'create user bigschema identified by B67_kuca_ecdf default tablespace APPDATA temporary tablespace TEMP profile DEFAULT account unlock';
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    execute immediate v_sql;
    v_sql := 'alter user bigschema quota unlimited on APPDATA';
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    execute immediate v_sql;
    v_sql := 'grant dba to bigschema';
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    execute immediate v_sql;
    v_sql := 'conn bigschema/"B67_kuca_ecdf"@'||pdb.name;
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    execute immediate v_sql;
    v_sql := 'drop table MV2OCI';
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    execute immediate v_sql;
    v_sql := 'create table MV2OCI tablespace APPDATA as select * from dba_objects';
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    execute immediate v_sql;
    v_sql := 'alter table MV2OCI nologging';
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    execute immediate v_sql;
    v_sql := 'show user';
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    execute immediate v_sql;
    v_sql := 'insert into MV2OCI select * from dba_objects';
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    execute immediate v_sql;
    v_sql := 'insert into MV2OCI select * from MV2OCI';
    DBMS_OUTPUT.PUT_LINE('Executing: ' || v_sql);
    execute immediate v_sql;
 END LOOP;
END;
/

Я просто хочу получить значение для переменной v_pdb из "выберите имя из v $ pdbs, где con_id = 3 и OPEN_MODE = 'READ WRITE'"

Ивызовите v_pdb следующим образом:

изменить набор сеансов container = v_pdb;запустить другие команды sql ... ......

Ответы [ 3 ]

1 голос
/ 22 мая 2019

Я не думаю, что это на самом деле имеет какое-либо отношение к вашей переменной pdb ...

Когда вы используете execute немедленно, вы не можете иметь a;в строке

Таким образом, для каждого выполняемого вами немедленного определения удалите;например,

execute immediate 'alter session set container='||pdb.name||';';

становится

execute immediate 'alter session set container='||pdb.name;
1 голос
/ 22 мая 2019

Существует несколько способов улучшить код и процесс кодирования:

  1. Исключить терминаторы операторов из динамического SQL: Как уже упоминалось, удалите ; из конца операторов SQL, используемых в динамическом SQL.
  2. Escape-строки: Строки в строках необходимо экранировать. Строка 'DATA' должна быть ''DATA''.
  3. Обратите внимание на полное сообщение об ошибке: Всегда отображать сообщение об ошибке whole , включая номер строки и номер столбца. Эта информация точно указывает на проблему.
  4. Используйте наименьший возможный пример: A меньший пример будет иметь меньше ошибок, что облегчит поиск реальной проблемы. И в процессе упрощения примера вы, скорее всего, сами найдете ответ.
1 голос
/ 22 мая 2019

Я считаю, что проблема в конечной точке с запятой в вашем динамическом SQL.Динамический SQL не включает конечную точку с запятой - поскольку динамический SQL является одним оператором, разделитель операторов не требуется.

После удаления конечной точки с запятой (и команды show) (aкоманда клиента)) это работает нормально.Но я не знаю хорошего способа получить DBMS_OUTPUT, если вы уже не находитесь в данном PDB.Это было опущено в этом примере.

declare
    v_sql varchar2(80);
BEGIN
    FOR pdb IN (select name from v$pdbs where con_id=3 and OPEN_MODE='READ WRITE')
        LOOP
            v_sql := 'alter session set container='||pdb.name;
            execute immediate V_SQL;
            DBMS_OUTPUT.ENABLE;
            v_sql := 'CREATE TABLE TEST_TABLE(LOREM_IPSUM NUMBER)';
            execute immediate V_SQL;
        END LOOP;
END;
/

Результат:

PL/SQL procedure successfully completed.

При переходе к PDB, TEST_TABLE теперь существует там.

...