为变量赋值并调用多个命令
Assign value to Variable and call in multiple commands
我需要为来自 select 查询输出的变量赋值,并将该变量调用到 sql 命令中
例如:我从 v$pdbs 得到 PDB_NAME 并将值赋给 v_pdb
我想在多个 sql 命令中使用 v_pdb 来 运行 针对 PDB
我尝试将 SELECT 查询的值分配给 v_pdb 并调用 'alter session set container=v_pdb' 中的 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;
/
我只是想从 "select name from v$pdbs where con_id=3 and OPEN_MODE='READ WRITE'"
中获取变量 v_pdb 的值
并调用 v_pdb 如下:
更改会话设置容器=v_pdb;
运行 其他 sql 命令
...
......
我认为问题出在动态 SQL 中的尾随 semi-colon。动态 SQL 不包括尾随 semi-colon -- 因为动态 SQL 是单个语句,所以不需要 statement-separator。
删除尾随 semi-colon(和 "show" 命令(客户端命令))后,一切正常。但我不知道有什么好方法可以让 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
现在在那里。
我认为它实际上与您的 pdb 变量没有任何关系...
当你使用立即执行时,你不能有;在字符串中
因此,对于您的每个立即执行语句,请删除 ;例如
execute immediate 'alter session set container='||pdb.name||';';
变成
execute immediate 'alter session set container='||pdb.name;
有几种方法可以改进代码和编码过程:
- Exclude statement terminators from dynamic SQL: 正如其他人提到的,从 SQL 中使用的语句末尾删除
;
动态 SQL.
- 转义字符串:字符串中的字符串需要转义。字符串
'DATA'
应该是 ''DATA''
.
- 注意完整的错误信息:总是显示整个错误信息,包括行号和列号。该信息恰好指出了问题所在。
- 使用尽可能小的例子:一个smaller example的错误会更少,更容易找到真正的问题。在简化示例的过程中,您可能会自己找到答案。
我需要为来自 select 查询输出的变量赋值,并将该变量调用到 sql 命令中
例如:我从 v$pdbs 得到 PDB_NAME 并将值赋给 v_pdb 我想在多个 sql 命令中使用 v_pdb 来 运行 针对 PDB
我尝试将 SELECT 查询的值分配给 v_pdb 并调用 'alter session set container=v_pdb' 中的 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;
/
我只是想从 "select name from v$pdbs where con_id=3 and OPEN_MODE='READ WRITE'"
中获取变量 v_pdb 的值并调用 v_pdb 如下:
更改会话设置容器=v_pdb; 运行 其他 sql 命令 ... ......
我认为问题出在动态 SQL 中的尾随 semi-colon。动态 SQL 不包括尾随 semi-colon -- 因为动态 SQL 是单个语句,所以不需要 statement-separator。
删除尾随 semi-colon(和 "show" 命令(客户端命令))后,一切正常。但我不知道有什么好方法可以让 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
现在在那里。
我认为它实际上与您的 pdb 变量没有任何关系...
当你使用立即执行时,你不能有;在字符串中
因此,对于您的每个立即执行语句,请删除 ;例如
execute immediate 'alter session set container='||pdb.name||';';
变成
execute immediate 'alter session set container='||pdb.name;
有几种方法可以改进代码和编码过程:
- Exclude statement terminators from dynamic SQL: 正如其他人提到的,从 SQL 中使用的语句末尾删除
;
动态 SQL. - 转义字符串:字符串中的字符串需要转义。字符串
'DATA'
应该是''DATA''
. - 注意完整的错误信息:总是显示整个错误信息,包括行号和列号。该信息恰好指出了问题所在。
- 使用尽可能小的例子:一个smaller example的错误会更少,更容易找到真正的问题。在简化示例的过程中,您可能会自己找到答案。