You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle中如何传递游标作为参数并正确调用?

解决Oracle中SYS_REFCURSOR直接引用字段的PLS-00487错误

错误原因

SYS_REFCURSOR是弱类型游标,无法直接通过游标变量访问字段;同时你在存储过程中重复声明了同名的rt_ba游标变量,覆盖了传入的参数,这两个问题共同导致了PLS-00487错误。

解决步骤

1. 定义匹配游标结果集的记录类型

需要先定义与游标查询列结构完全匹配的记录类型,确保字段顺序、数据类型和查询结果一致:

-- 可在存储过程内部或包级别定义该类型
TYPE rt_ba_rec IS RECORD (
    -- 对应idm_ap_mtc_acl_header_tmp表的字段
    no_ba          idm_ap_mtc_acl_header_tmp.no_ba%TYPE,
    req_id         idm_ap_mtc_acl_header_tmp.req_id%TYPE,
    tgl_ba         idm_ap_mtc_acl_header_tmp.tgl_ba%TYPE,
    tax_name       idm_ap_mtc_acl_header_tmp.tax_name%TYPE,
    dc_code        idm_ap_mtc_acl_header_tmp.dc_code%TYPE,
    -- 对应idm_ap_mtc_acl_lines_tmp表的字段
    jenis_pekerjaan idm_ap_mtc_acl_lines_tmp.jenis_pekerjaan%TYPE,
    deskripsi_pekerjaan idm_ap_mtc_acl_lines_tmp.deskripsi_pekerjaan%TYPE,
    akun           idm_ap_mtc_acl_lines_tmp.akun%TYPE,
    rate_ppn       idm_ap_mtc_acl_lines_tmp.rate_ppn%TYPE,
    dpp            idm_ap_mtc_acl_lines_tmp.dpp%TYPE,
    ppn            idm_ap_mtc_acl_lines_tmp.ppn%TYPE,
    total_realisasi idm_ap_mtc_acl_lines_tmp.total_realisasi%TYPE,
    major          idm_ap_mtc_acl_lines_tmp.major%TYPE,
    minor          idm_ap_mtc_acl_lines_tmp.minor%TYPE,
    sla            idm_ap_mtc_acl_lines_tmp.sla%TYPE
);

2. 修改存储过程,通过记录变量访问游标数据

移除多余的游标变量声明,将游标数据FETCH到记录变量后再访问字段:

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
   TYPE rt_ba_rec IS RECORD (
       no_ba          idm_ap_mtc_acl_header_tmp.no_ba%TYPE,
       req_id         idm_ap_mtc_acl_header_tmp.req_id%TYPE,
       tgl_ba         idm_ap_mtc_acl_header_tmp.tgl_ba%TYPE,
       tax_name       idm_ap_mtc_acl_header_tmp.tax_name%TYPE,
       dc_code        idm_ap_mtc_acl_header_tmp.dc_code%TYPE,
       jenis_pekerjaan idm_ap_mtc_acl_lines_tmp.jenis_pekerjaan%TYPE,
       deskripsi_pekerjaan idm_ap_mtc_acl_lines_tmp.deskripsi_pekerjaan%TYPE,
       akun           idm_ap_mtc_acl_lines_tmp.akun%TYPE,
       rate_ppn       idm_ap_mtc_acl_lines_tmp.rate_ppn%TYPE,
       dpp            idm_ap_mtc_acl_lines_tmp.dpp%TYPE,
       ppn            idm_ap_mtc_acl_lines_tmp.ppn%TYPE,
       total_realisasi idm_ap_mtc_acl_lines_tmp.total_realisasi%TYPE,
       major          idm_ap_mtc_acl_lines_tmp.major%TYPE,
       minor          idm_ap_mtc_acl_lines_tmp.minor%TYPE,
       sla            idm_ap_mtc_acl_lines_tmp.sla%TYPE
   );
   l_ba_rec rt_ba_rec; -- 声明记录变量
   r_tax_info       rt_tax_info;
BEGIN
   ------------ setup ------------
   -- 从传入的游标中获取一行数据到记录变量
   FETCH r_ba INTO l_ba_rec;
   
   -- 检查是否获取到有效数据
   IF r_ba%FOUND THEN
       r_tax_info := get_tax_code (
                         p_date           => l_ba_rec.tgl_ba,
                         p_group_tax_name => l_ba_rec.tax_name,
                         p_ppn_rate       => l_ba_rec.rate_ppn,
                         p_dc_code        => l_ba_rec.dc_code);
   ELSE
       -- 处理无数据场景,可根据业务需求调整
       RAISE_APPLICATION_ERROR(-20001, '游标中无可用数据');
   END IF;

   -- 若游标返回多行数据,需用循环遍历处理:
   -- LOOP
   --    FETCH r_ba INTO l_ba_rec;
   --    EXIT WHEN r_ba%NOTFOUND;
   --    -- 此处添加每行数据的业务逻辑
   -- END LOOP;
END;

3. 关键注意事项

  • 记录类型的字段顺序、数据类型必须与游标查询的列完全匹配,否则会触发类型不匹配错误
  • 若游标返回多行数据,必须使用循环遍历所有行,避免只处理第一行
  • 存储过程内部不要重复声明与参数同名的变量,避免覆盖传入值

内容的提问来源于stack exchange,提问作者Steven Phan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 10:55:17