SYS_REFCURSOR out 参数 - 运行存储过程失败
Posted
技术标签:
【中文标题】SYS_REFCURSOR out 参数 - 运行存储过程失败【英文标题】:SYS_REFCURSOR out parameter - running stored procedure fails 【发布时间】:2016-07-19 15:53:49 【问题描述】:我来自 SQL Server 背景,但我在 Oracle 中遇到了这个问题。数据库中所有已配置的存储过程都需要传入类型为“sys_refcursor”的参数。简而言之,他们这样做(存储过程要复杂得多,但整个光标就是我要了解的):
CREATE OR REPLACE PROCEDURE xxx_API_TEST
(
TESTCURSOR OUT SYS_REFCURSOR
) AS
BEGIN
OPEN CURS FOR
SELECT * FROM SOMETABLE;
END xxx_API_TEST;
所以 - 在 Oracle SQL Developer 中我可以毫无问题地运行它 - 并在“输出变量”窗口中查看光标的输出。
但是,不必每次我想重新测试时都重新加载对话框 - 我认为可以将对话框中的 PL/SQL 复制到新工作表,然后根据需要运行它to - 调整参数以适应 - 所以在这种情况下,我会运行:
DECLARE
TESTCURSOR SYS_REFCURSOR;
BEGIN
xxx_API_TEST(
TESTCURSOR => TESTCURSOR
);
/* Legacy output:
DBMS_OUTPUT.PUT_LINE('TESTCURSOR = ' || TESTCURSOR );
*/
:TESTCURSOR := TESTCURSOR; --<-- Cursor
--rollback;
END;
这与运行对话框中显示的完全相同。
但是,如果我这样做 - 它只会引发错误 - 说明:
Error starting at line : 1 in command -
<snip>
Error report -
ORA-06550: line 11, column 20:
PLS-00382: expression is of wrong type
ORA-06550: line 11, column 3:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
我不知道如何诊断这个。它在对话框中运行良好但在工作表中运行良好的事实令人费解 - 检查发送到数据库的内容我看不出它实际使用的 SQL 有任何差异。
有趣的是,如果我从工作表中运行此代码 - 它会弹出一个对话框来询问 TESTCURSOR 的值 - “运行”对话框没有这样做。我只是按 OK - 但我尝试勾选和取消勾选“Null”复选框均无济于事。
非常感谢任何帮助。它是甲骨文 12c。如果您需要更多信息,请告诉我。
干杯, 托尼
更新:2016 年 7 月 20 日
我最终将值从 fetch 中提取到变量中,然后转储到 dbms_output - 这为我提供了重复运行相同存储过程所需的内容。 例如
loop
fetch testcursor into Res, ActDate<snip>;
exit when testcursor%notfound;
DBMS_OUTPUT.PUT_LINE(Res || ' | ' || ActDate etc etc);
end loop;
close testcursor;
【问题讨论】:
【参考方案1】:运行对话框是根据过程规范生成的,因此知道testcursor
的正确类型,但是当您将其粘贴到工作表中时它不会,并且似乎将其定义为文本字符串。从 SQL Developer 4.0.3.16 开始,工作表绑定值提示似乎无法更改数据类型。
至于如何在 SQL Dev 中创建带有游标输出的可重用测试脚本,我不知道。 (我通常使用 PL/SQL Developer 可以做到这一点,但它不是免费软件。)
编辑:在这个线程中,一个解决方案是编写一个包装函数并从对偶中选择它。我刚刚试过,你没有得到一个网格,但是你得到了一种调试输出而不需要太多的努力:
Oracle SQL Developer: Show REFCURSOR Results in Grid?
【讨论】:
谢谢威廉 - 至少我不会发疯。最终只是像上面一样运行它,但是为每一列获取变量,例如loop fetch testcursor into Res, ActDate<snip>; exit when testcursor%notfound; DBMS_OUTPUT.PUT_LINE(Res || ' | ' || ActDate etc etc); end loop; close testcursor;
我已经更新了我的答案,提供了一个可能有帮助的早期问题的链接。那里的建议是将过程包装在一个函数中并从对偶中选择它。以上是关于SYS_REFCURSOR out 参数 - 运行存储过程失败的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 out sys_refcursor 参数执行 oracle 过程?
创建具有 SYS_REFCURSOR 作为输出参数的 mysql 过程时出错