【问题标题】:ORACLE call stored procedure inside package with cursor typeORACLE 使用游标类型调用包内的存储过程
【发布时间】:2020-08-01 06:57:12
【问题描述】:

我真的很难在下面调用存储过程。我正在使用 oracle sql developer,版本 19.2。我尝试的是this answer,但我收到错误(与 cmets 中描述的错误相同)。为什么sql developer调用这么简单的存储过程这么难?

create or replace PACKAGE BODY "PCK_FIRST" IS
      PROCEDURE GET_GETNAMES(
        USER_ID IN NUMBER,    
        M_RESULT OUT TYPES.CURSOR_TYPE
      ) IS
      BEGIN
        OPEN M_RESULT FOR
        SELECT * FROM PER_NAMES WHERE ID = USER_ID;
      END;

END PCK_FIRST;

【问题讨论】:

  • 您链接到的答案的 cmets 中描述了几个不同的错误。你具体得到什么错误?你到底是如何调用这个程序的。在您对另一个答案的评论中,您指出此过程在一个包中。那是对的吗?而且我认为这与定义 cursor_typetypes 包不同?
  • @JustinCave - 是的,程序在包内。我已经编辑了我的代码。抱歉,我不明白你关于类型的问题的另一部分?
  • 过程的声明表明m_result 的类型为types.cursor_type。这意味着您有一个 types 包,其中定义了 cursor_type。我的猜测是它被定义为一个简单的弱类型引用游标(即它与sys_refcursor 相同)但这只是一个猜测。您用来调用此过程的代码是什么?您遇到了什么错误?
  • @JustinCave - 这个游标应该在哪里声明?确定它在“类型”文件夹中 - 我已经检查了所有类型。错误是:绑定变量“c”未声明
  • cursor_typetypes包中的声明是什么?它是一个简单的弱类型引用游标吗?您用来调用该过程的代码是什么?我假设这就是变量c 在没有被声明的情况下被使用的地方。

标签: oracle plsql


【解决方案1】:

首先我建议您运行此程序,然后再次尝试执行您的程序

create or replace package types as
   type cursor_type is ref cursor;
end
/

否则试试这个改变TYPES.CURSOR_TYPE with sys_refcursor

--example
create table test_user (
   user_id number(19) not null,
   username varchar2(50)
);

insert into test_user values (1, 'user1');

insert into test_user values (2, 'user2');

create or replace procedure test_proc (
   p_user_id in number,
   p_out_rec out sys_refcursor
)
is
   l_out SYS_REFCURSOR;
begin
   open l_out for
      select * 
        from test_user
       where user_id = p_user_id;
end;
/

declare
   l_output sys_refcursor;
   l_userid number := 1;
begin
  test_proc(1, l_output);
end;

PL/SQL procedure successfully completed.

【讨论】:

  • 问题是我无法更改存储过程。它在更大的包装内。我只想这样称呼它。为什么更改光标如此重要?
【解决方案2】:

声明一个类型为TYPES.CURSOR_VALUE的变量,然后将其用作游标的输出:

DECLARE
  cur    TYPES.CURSOR_TYPE;
  p_id   PER_NAMES.ID%TYPE;
  p_name PER_NAMES.NAME%TYPE;
BEGIN
  PCK_FIRST.get_getnames( 1, cur );
  LOOP
    FETCH cur INTO p_id, p_name;
    EXIT WHEN cur%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE( p_id || ': ' || p_name );
  END LOOP;
  CLOSE cur;
END;
/

db小提琴here


如果你想在 SQL Developer 中调用它,那么:

VARIABLE cur REFCURSOR;
EXECUTE pck_first.get_getnames(1, :cur);
PRINT cur;

并使用 F5 将其作为脚本运行(而不是使用 Ctrl-Enter 作为单个语句)。

【讨论】:

  • 非常感谢您的代码,它可以工作。有没有办法让输出看起来更像数据表输出,就像 SELECT * FROM PER_NAMES 一样。 print cur 给出输出,没问题,但看起来像脚本输出。
  • 我不知道。
猜你喜欢
  • 2012-10-13
  • 1970-01-01
  • 1970-01-01
  • 2020-02-14
  • 1970-01-01
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 2014-04-22
相关资源
最近更新 更多