【问题标题】:ORACLE - can i pass cursor in a parameter and how to use it?ORACLE - 我可以在参数中传递游标吗?如何使用它?
【发布时间】:2023-01-10 14:46:17
【问题描述】:

这是 oracle 程序之一。有一个名为 r_ba 的游标。

DECLARE
   r_ba SYS_REFCURSOR;
BEGIN
   OPEN r_ba FOR
      SELECT head.*,
             line.jenis_pekerjaan,
             line.deskripsi_pekerjaan,
             line.akun,
             line.rate_ppn,
             line.dpp,
             line.ppn,
             line.total_realisasi,
             line.major,
             line.minor,
             line.sla
        FROM idm_ap_mtc_acl_header_tmp head, idm_ap_mtc_acl_lines_tmp line
       WHERE head.no_ba = line.no_ba AND head.req_id = line.req_id AND head.req_id = n_req_id;

   create_invoice_ap2 (
      p_org_id      => p_org_id,
      p_user_id     => p_user_id,
      p_branch_code => v_branch_code,
      r_ba          => r_ba);
END;

以及如何在此过程中调用该游标?

PROCEDURE create_invoice_ap2 (p_org_id      IN NUMBER,
                              p_user_id     IN NUMBER,
                              p_branch_code IN VARCHAR2,
                              r_ba          IN SYS_REFCURSOR)
IS
   r_tax_info       rt_tax_info;
   rt_ba            SYS_REFCURSOR;
BEGIN
   ------------ setup ------------
   r_tax_info      := get_tax_code (
                         p_date           => rt_ba.tgl_ba,
                         p_group_tax_name => rt_ba.tax_name,
                         p_ppn_rate       => rt_ba.ppn_rate,
                         p_dc_code        => rt_ba.dc_code);
END;

甲骨文给我错误

[Error] PLS-00487 (707: 64): PLS-00487: Invalid reference to variable 'RT_BA'

任何人都可以建议我实现这一目标的方法吗?

谢谢

【问题讨论】:

    标签: oracle plsql oracle11g


    【解决方案1】:

    如果您将 refcursor 传递给名为 r_ba 的参数,那么 - 我相信 - 您应该使用它,而不是声明另一个 (rt_ba):

    PROCEDURE create_invoice_ap2 (p_org_id      IN NUMBER,
                                  p_user_id     IN NUMBER,
                                  p_branch_code IN VARCHAR2,
                                  r_ba          IN SYS_REFCURSOR)
    IS
       r_tax_info       rt_tax_info;
       -- rt_ba            SYS_REFCURSOR;        --> you don't need it
    BEGIN
       ------------ setup ------------
       r_tax_info      := get_tax_code (
                             p_date           => r_ba.tgl_ba,
                             p_group_tax_name => r_ba.tax_name,
                             p_ppn_rate       => r_ba.ppn_rate,
                             p_dc_code        => r_ba.dc_code);
    END;                                         ----
                                                  ^
                                                  |
                                           r_ba, not rt_ba
    

    另外,请注意,您通常应该避免使用 select *,因为如果存在与其他表中的列同名的列,它会导致歧义,因此 Oracle 不知道您要使用哪一个。

    错别字也是如此;例如,在匿名 PL/SQL 块中,您选择 line.rate_ppn,而过程使用 p_ppn_rate => r_ba.ppn_raterate_ppnppn_rate)。或许没关系,因为头表中有 ppn_rate 列(在 select head.* 中)但是 - 再一次 - 这很难调试。


    此外,你不能那样使用 refcursor - 你必须拿来从中。查看基于 Scott 示例模式的示例。这是一个接受 refcursor 作为参数的过程,并且做某事用它:

    SQL> create or replace procedure p_test (r_ba in sys_refcursor)
      2  is
      3    l_dname varchar2(20);
      4  begin
      5    l_dname := r_ba.dname;
      6  end;
      7  /
    
    Warning: Procedure created with compilation errors.
    
    SQL> show err
    Errors for PROCEDURE P_TEST:
    
    LINE/COL ERROR
    -------- -----------------------------------------------------------------
    5/3      PL/SQL: Statement ignored
    5/19     PLS-00487: Invalid reference to variable 'R_BA'
    SQL>
    

    看?你得到了同样的错误。因此,获取:

    SQL> create or replace procedure p_test (r_ba in sys_refcursor)
      2  is
      3    l_dname varchar2(20);
      4  begin
      5    loop
      6      fetch r_ba into l_dname;
      7      exit when r_ba%notfound;
      8      dbms_output.put_line(l_dname);
      9    end loop;
     10  end;
     11  /
    
    Procedure created.
    
    SQL> declare
      2    r_ba sys_refcursor;
      3  begin
      4    open r_ba for select dname from dept;
      5    p_test (r_ba);
      6  end;
      7  /
    ACCOUNTING
    RESEARCH
    SALES
    OPERATIONS
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    现在可以了。

    我不知道你在用 r_tax_info 做什么,refcursor 包含多少行(无论你是否需要使用循环),但是 - 这是一般的想法。先获取,再使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-03
      • 2016-05-26
      • 1970-01-01
      • 1970-01-01
      • 2012-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多