在Oracle中,EXECUTE IMMEDIATE比使用dbms_sql包更简单,但交叉租户查询除外,因为12c中的dbms_sql允许容器参数。
然而,在一个小小的测试中,我什么都没得到。即,
set serveroutput on
declare
ret pls_integer;
cnt pls_integer := 0;
cols number := 0;
ctx varchar2(128) := NULL;
cur number;
stmt varchar2(100);
begin
stmt := 'select count(*) from scott.emp';
cur := dbms_sql.open_cursor;
dbms_sql.parse(c => cur,
statement => stmt,
language_flag => dbms_sql.native,
container => ctx);
dbms_sql.define_column(cur, 1, cnt);
ret := dbms_sql.execute(cur);
dbms_output.put_line('execute = '||ret);
ret := dbms_sql.fetch_rows(cur);
dbms_output.put_line(' fetch = '||ret);
dbms_output.put_line(stmt||' = '||cnt);
dbms_sql.close_cursor(cur);
end;
/
容器为null时 - 表示当前或忽略将允许将查询发送到目标容器。然而我怀疑我错过了一些微不足道的东西,因此我的问题;提前致谢。样本输出:
SQL> show con_name
CON_NAME
------------------------------
PDB1
SQL> set echo on
SQL> @f
SQL> set serveroutput on
SQL> declare
2 ret pls_integer;
3 cnt pls_integer := 0;
4 cols number := 0;
5 ctx varchar2(128) := NULL;
6 cur number;
7 stmt varchar2(100);
8 begin
9 stmt := 'select count(*) from scott.emp';
10 cur := dbms_sql.open_cursor;
11 dbms_sql.parse(c => cur,
12 statement => stmt,
13 language_flag => dbms_sql.native,
14 container => ctx);
15 dbms_sql.define_column(cur, 1, cnt);
16 ret := dbms_sql.execute(cur);
17 dbms_output.put_line('execute = '||ret);
18 ret := dbms_sql.fetch_rows(cur);
19 dbms_output.put_line('fetch = '||ret);
20 dbms_output.put_line(stmt||' = '||cnt);
21 dbms_sql.close_cursor(cur);
22 end;
23 /
execute = 0
fetch = 1
select count(*) from scott.emp = 0
PL/SQL procedure successfully completed.
答案 0 :(得分:2)
您需要从结果集中获取实际列值:
dbms_sql.column_value(cur, 1, cnt);
COLUMN_VALUE程序
此过程返回给定游标中给定位置的cursor元素的值。此过程用于访问通过调用FETCH_ROWS获取的数据。
所以你的代码是:
set serveroutput on
declare
ret pls_integer;
cnt pls_integer := 0;
cols number := 0;
ctx varchar2(128) := NULL;
cur number;
stmt varchar2(100);
begin
stmt := 'select count(*) from scott.emp';
cur := dbms_sql.open_cursor;
dbms_sql.parse(c => cur,
statement => stmt,
language_flag => dbms_sql.native,
container => ctx);
dbms_sql.define_column(cur, 1, cnt);
ret := dbms_sql.execute(cur);
dbms_output.put_line('execute = '||ret);
ret := dbms_sql.fetch_rows(cur);
dbms_output.put_line(' fetch = '||ret);
-- get the actual value from the column into its variable
dbms_sql.column_value(cur, 1, cnt);
dbms_output.put_line(stmt||' = '||cnt);
dbms_sql.close_cursor(cur);
end;
/
如果我这样做(不可否认的是11g,那么没有container
论证 - 这似乎与你的实际问题无关)和hr.employees
表反而是,见:
execute = 0
fetch = 1
select count(*) from employees = 107
PL/SQL procedure successfully completed.
SQL> select count(*) from employees;
COUNT(*)
----------
107