plsql 使用 dbms_sql 12c 选择返回值
Posted
技术标签:
【中文标题】plsql 使用 dbms_sql 12c 选择返回值【英文标题】:plsql select return value using dbms_sql 12c 【发布时间】:2016-10-20 15:22:24 【问题描述】:在 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.
【问题讨论】:
您希望从上一次dbms_output
调用、容器名称(来自 ctx)或计数结果中看到什么?
哦,我在尝试各种事情;我更新了帖子以将 define_columns 恢复为仅 1 列到 cnt 变量。我原以为是 14 岁。
【参考方案1】:
您需要从结果集中获取实际列值:
dbms_sql.column_value(cur, 1, cnt);
From the documentation:
COLUMN_VALUE 过程 此过程返回给定游标中给定位置的游标元素的值。此过程用于访问通过调用 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
【讨论】:
啊,原来贴的代码错了;它已经更新了。你的版本类似。最终,这将是接收语句和容器上下文的例程的起源。所以,现在是 12c,我有兴趣寻求帮助,谢谢。 @slashlos - 但据我所知,容器与计数问题无关;您修改后的代码仍然缺少column_value
子句?
您是否还期望使用它运行的实际容器来更新ctx
?我看不到任何暗示应该发生的事情,it's an IN parameter...
ctx 是一个未来;是的,column_value 就是我所缺少的!以上是关于plsql 使用 dbms_sql 12c 选择返回值的主要内容,如果未能解决你的问题,请参考以下文章
oracle12C安装完成后,尝试用PLSQL连接PDB数据库,发现个问题PDB有没有SID?使用服务名来连接还是用SID?