使用 sys_refcursor 执行 pl sql 存储过程时出错

Posted

技术标签:

【中文标题】使用 sys_refcursor 执行 pl sql 存储过程时出错【英文标题】:Error while executing pl sql stored procedure with sys_refcursor 【发布时间】:2015-01-28 14:02:44 【问题描述】:

当我尝试执行以下查询时:

 declare
 v_rc    sys_refcursor;
wfrt_a1 varchar2(800 byte);
             wfrt_a2 varchar2(800 byte);
             wfrt_a3 varchar2(800 byte);
             wfrt_a4 varchar2(800 byte);
             wfrt_a5 varchar2(800 byte);

             wfrt_a6 varchar2(800 byte);
              wfrt_a7 varchar2(800 byte);
             wfrt_a8 varchar2(800 byte);
             wfrt_a9 varchar2(800 byte);
             wfrt_a10 varchar2(800 byte);

             wfrt_a11 varchar2(800 byte);
             wfrt_a12 varchar2(800 byte);
             wfrt_a13 varchar2(800 byte);
             wfrt_a14 varchar2(800 byte);

             wfrt_a15 varchar2(800 byte);
             wfrt_a16 varchar2(800 byte);
             wfrt_a17 varchar2(800 byte);
             wfrt_a18 varchar2(800 byte);
             wfrt_a19 varchar2(800 byte);

             wfrt_a20 varchar2(800 byte);
             wfrt_a21 varchar2(800 byte);
             wfrt_a22 varchar2(800 byte);
             wfrt_a23 varchar2(800 byte);
             wfrt_a24 varchar2(800 byte);

             wfrt_a25 varchar2(800 byte);
             wfrt_a26 varchar2(800 byte);
             wfrt_a27 varchar2(800 byte);
             wfrt_a28 varchar2(800 byte);
             wfrt_a29 varchar2(800 byte);

             wfrt_a30 varchar2(800 byte);
             wfrt_a31 varchar2(800 byte);
              wfrt_a32 varchar2(800 byte);
               wfrt_a33 varchar2(800 byte);
                wfrt_a34 varchar2(800 byte);
             wfrt_a35 varchar2(800 byte);
             wfrt_a36 varchar2(800 byte);

                              wfrt_a37 varchar2(800 byte);
             wfrt_a38 varchar2(800 byte);
             wfrt_a39 varchar2(800 byte);
             wfrt_a40 varchar2(800 byte);
             wfrt_a41 varchar2(800 byte);
             wfrt_a42 varchar2(800 byte);
               begin
 execute My_Procedure_Name (:v_rc  ,'Investments Series','31-12-2012','Dealer  Group','All Adv');  -- This returns an open cursor
loop
 fetch v_rc into wfrt_a1, wfrt_a2, wfrt_a3, wfrt_a4,wfrt_a5,wfrt_a6,wfrt_a7,wfrt_a8,wfrt_a9,wfrt_a10,wfrt_a11,wfrt_a12,wfrt_a13,wfrt_a14,wfrt_a15,wfrt_a16,wfrt_a17
 ,wfrt_a18,wfrt_a19,wfrt_a20,wfrt_a21,wfrt_a22,wfrt_a23,wfrt_a24,wfrt_a25,wfrt_a26,wfrt_a27,wfrt_a28,wfrt_a29,wfrt_a30,wfrt_a31,wfrt_a32,wfrt_a33,wfrt_a34,wfrt_a35
 ,wfrt_a36,wfrt_a37,wfrt_a38,wfrt_a39,wfrt_a40,wfrt_a41,wfrt_a42;
 exit when v_rc%NOTFOUND;  -- Exit the loop when we've run out of data
 dbms_output.put_line('Row: '||v_rc%ROWCOUNT||' # '||wfrt_a1||','||wfrt_a2||','||wfrt_a3||','||wfrt_a4||','||wfrt_a5||','||wfrt_a6||','||wfrt_a7||','||wfrt_a8||','||wfrt_a9 
 ||','||wfrt_a10||','||wfrt_a11||','||wfrt_a12||','||wfrt_a13||','||wfrt_a14||','||wfrt_a15||','||wfrt_a16||','||wfrt_a17
 ||','||wfrt_a18||','||wfrt_a19||','||wfrt_a20||','||wfrt_a21||','||wfrt_a22||','||wfrt_a23||','||wfrt_a24||','||wfrt_a25
 ||','||wfrt_a26||','||wfrt_a27||','||wfrt_a28||','||wfrt_a29||','||wfrt_a30||','||wfrt_a31||','||wfrt_a32||','||wfrt_a33
 ||','||wfrt_a34||','||wfrt_a35||','||wfrt_a36||','||wfrt_a37||','||wfrt_a38||','||wfrt_a39||','||wfrt_a40||','||wfrt_a41||','||wfrt_a42);
end loop;
  close v_rc;
 end;

我遇到以下错误: ORA-06550:第 56 行,第 9 列: PLS-00103:遇到符号 “My_Procedure_Name”预期以下情况之一 :=.(@%;立即

注意:我的程序如下所示

CREATE OR REPLACE PROCEDURE USER.My_Procedure_Name (c1                IN OUT SYS_REFCURSOR,
                                           code IN     VARCHAR2,
                                           date  IN     VARCHAR2,
                                           group     IN     VARCHAR2,
                                          adv        IN     VARCHAR2
                                          )

请建议,我在哪里做错了?谢谢。

【问题讨论】:

【参考方案1】:

您没有在 PL/SQL 中显式地 execute 过程调用,因此请删除该词:

begin
    My_Procedure_Name (v_rc  , 'Investments Series','31-12-2012',
        'All Dealer Group','All Adviser');  -- This returns an open cursor
    loop

在 PL/SQL 中,您确实有 execute immediate 用于动态 SQL;错误消息是因为它在期望看到单词immediate 时看到了您的过程名称。您可能会将其与 SQL*Plus 和 SQL Developer execute 命令混淆,后者是小型匿名块的简写。

当您真的只想要本地声明的v_rc 时,您将:v_rc 作为第一个参数传递,这表示绑定变量。如果它没有抱怨,那么您可能已经将其定义为客户端变量,如果您从中收到“错误的数字或类型”错误,则该变量的类型可能不同。

传递字符串而不是日期似乎也有点奇怪。

【讨论】:

感谢您的意见。但是我收到了这个错误:现在,它的意思是“调用 'My_Stored_Procedure' 第 56 行,第 2 列的参数类型错误。PL/SQL:语句被忽略” @bapi - 可能是因为第一个参数之前的冒号;在运行此块之前,您是否在您的客户端中完成了 variable v_rc number 或其他操作? 日期转换是在 SP 内进行的,我不认为,日期参数有任何问题。另外,这是我从 s-s-rS 报告前端传递日期的方式。但是,当我使用您建议的修改执行查询时,出现另一个错误:“结果集变量或查询的返回类型不匹配” - 我对我的问题几乎没有修改。如何重新爱上这个?谢谢。 @bapi - 返回类型是什么?我很困惑......完整的错误堆栈是什么?在该过程中,当您打开游标时,您的选择列表项的数量或类型是否与您要提取的 42 个变量不同? 这是我单击详细信息时得到的结果:PL/SQL:结果集变量或查询的返回类型不匹配原因:查询中的列数和/或类型不匹配结果集变量声明的返回类型,或两个结果集变量的声明类型不匹配。行动:更改程序声明或声明。验证变量在执行期间实际引用的查询。

以上是关于使用 sys_refcursor 执行 pl sql 存储过程时出错的主要内容,如果未能解决你的问题,请参考以下文章

Oracle - pl sql 从 SYS_REFCURSOR 中选择

在 PL\SQL 中设置 SYS_REFCURSOR 以返回数据集

将常规 CURSOR 传递给需要 SYS_REFCURSOR 的 PL/SQL 过程

oracle 合并多个sys_refcursor

如何在c#中使用oledb执行pl sql块

如何使用 out sys_refcursor 参数执行 oracle 过程?