使用 DBMS_SQL.Execute_and_fetch - 获取 Ref 游标的游标号 (10g)

Posted

技术标签:

【中文标题】使用 DBMS_SQL.Execute_and_fetch - 获取 Ref 游标的游标号 (10g)【英文标题】:Using DBMS_SQL.Execute_and_fetch - Get cursor number of a Ref Cursor (10g) 【发布时间】:2014-05-07 09:09:24 【问题描述】:

使用Oracle 10g DBMS,我想在一个过程中应用DBMS_SQL.execute_and_fetch。我拒绝EXECUTE IMMEDIATE,因为我想绑定命名变量并且不依赖它们在语句中的顺序。

问题是我无法处理传递给我的过程的olist ref 游标参数的游标号。这是我正在尝试做的示例代码 sn-p。

PROCEDURE TestProc( vuserid INTEGER,
                    olist   OUT refcur)
IS
  cursor_num INTEGER;
  vsql       VARCHAR2(1000 CHAR);
BEGIN
  vsql := 'SELECT * FROM USERS WHERE USER_ID = :user_id';

  /*creates a new cursor. Need to use the cursor that is passed to my procedure*/
  /*cursor_num := dbms_sql.open_cursor; */

  /*Only available in 11g onwards        */
  /*cursor_num := dbms_sql.to_cursor_number(olist); */

  sys.dbms_sql.parse(cursor_num, vsql, sys.dbms_sql.native);
  sys.dbms_sql.bind_variable(cursor_num, ':user_id', vuserid);
  sys.dbms_sql.execute_and_fetch(cursor_num, FALSE);
END TestProc;

如何在我的特定情况下成功使用DBMS_SQL.execute_and_fetch 过程,其中用于获取的游标是我传入的引用游标?

【问题讨论】:

我假设olist 必须是IN 参数,不是吗? 嗨,温弗里德。不,它是书面的。我正在使用 ODP.Net 调用该过程,根据文档,它应该是 OUT。见here 【参考方案1】:

我假设您正在寻找这个:

PROCEDURE TestProc (
      vUserid   INTEGER,
      olist              OUT   SYS_REFCURSOR)
IS
   cursor_num INTEGER;
   vSQL VARCHAR2(1000 CHAR);
    result NUMBER;
BEGIN   
    vSQL := 'SELECT * FROM USERS WHERE USER_ID = :user_id';

    cursor_num := DBMS_SQL.OPEN_CURSOR;
    DBMS_SQL.PARSE(cursor_num,vSQL,DBMS_SQL.NATIVE);
    DBMS_SQL.BIND_VARIABLE(cursor_num, ':user_id', vUserid);
    result := DBMS_SQL.EXECUTE(cursor_num);
    olist := DBMS_SQL.TO_REFCURSOR(cursor_num);

END TestProc;

然后调用块可以使用FETCH olist INTO...FETCH olist BULK COLLECT INTO... 来获取您的查询结果。

但您必须至少运行 Oracle 11,否则它不可用。

【讨论】:

感谢 Wernfried。但我别无选择。正如我在问题开始时所说的那样,我正在使用 10g。否则我可以使用 DBMS_SQL.TO_CURSOR_NUMBER(oList) 来获取游标编号。我想要的是一种在 10g 中获取光标编号的方法。谢谢。 那么光标编号就是cursor_num 的值。 TO_CURSOR_NUMBER(olist) 你可以在OPEN olist FOR SELECT ... 之后使用,e.i. cursor_num 等于 TO_CURSOR_NUMBER(olist) 是的,但我很抱歉 - 你错过了我的意思。我需要在 10g 中做这些事情之一 - 而不是 11g。无论我使用 TO_CURSOR_NUMBER 还是(如您的代码 DBMS_SQL.TO_REFCURSOR)对我来说都是无用的,因为它们都不适用于 10g。有没有办法在 10g 中做到这一点?再次感谢。 T 那是不可能的,除非你升级到Oracle 11g。顺便说一句,Oracle 10 几乎与 Windows XP 一样古老,并且很久以来就不再支持了。 我很清楚这一点,但这不是我能控制的。我用我可以支配的东西工作。碰巧的是,我们将在接下来的 6 个月内升级到 12c,但我有一个发布版本将在一个月内到期,所以这不是一个选择。

以上是关于使用 DBMS_SQL.Execute_and_fetch - 获取 Ref 游标的游标号 (10g)的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)