oracle - 在 sys_refcursor 中使用 oracle 游标

标签 oracle plsql cursors

我有一个 PL/SQL 包,它根据您传递的 id 返回 sys_refcursor。我想迭代一些 id 并创建一个新的引用游标,其中为每个 id 重复原始结果集中的一列。 (有点像交叉表。)PL/SQL block 的非常简化的版本如下所示:

create or replace package body dashboard_package is

   procedure visits(RC in out sys_refcursor, IdNumber varchar2) as 
   BEGIN

      OPEN RC FOR 


      select *
  from (
        select cat, cat_order, subcat, label_text
               , trim(to_char(sum(v.current_month),'9,999,999,999')) current_month
               , trim(to_char(sum(v.ly_month),'9,999,999,999')) ly_month
               , trim(to_char(sum(v.ytd_tot),'9,999,999,999')) ytd_tot
               , trim(to_char(sum(v.lytd_tot),'9,999,999,999')) lytd_tot
               , trim(to_char(sum(v.ly_tot),'9,999,999,999')) ly_tot
          from dashboard v
         where v.id_number = IdNumber
         group by cat_order, subcat, cat, label_text

            union all
            ...
             ) a

     order by cat_order, subcat;

       END; 
END;

我想如果我有这样的东西

create or replace procedure test_refcur is
   refCursorValue SYS_REFCURSOR;   
begin
   dashboard_package.visits(refCursorValue,12345);
   for cursrow in refCursorValue loop
      dbms_output.put_line(cursrow.ytd_tot);
   end loop;
end test_refcur;

工作,我可以从那里拿走它......有什么想法吗?或者也许澄清我应该问的问题。

最佳答案

如果您有多个 ID,那么一等奖将是仅运行一个 SQL 查询来一次获取批处理,使用 ID 的批量绑定(bind)。这可能需要修改 dashboard_package.visits,或者编写新版本的 visits 过程来接受 PL/SQL ID 表而不是单个 ID。

如果您无暇修改dashboard_package,那么您可以编写一个管道函数来返回一组ID 的行:

-- create some helper types for the pipelined function
create type visitobj as object
(id             number
,cat            dashboard.cat%type
,cat_order      dashboard.cat_order%type
,subcat         dashboard.subcat%type
,label_text     dashboard.label_text%type
,current_month  varchar2(13)
,ly_month       varchar2(13)
,ytd_tot        varchar2(13)
,lytd_tot       varchar2(13)
,ly_tot         varchar2(13));
create type visittable as table of visitobj;

create or replace function test_refcur
   return visittable deterministic pipelined is
   refCursorValue SYS_REFCURSOR;
   cat            dashboard.cat%type;
   cat_order      dashboard.cat_order%type;
   subcat         dashboard.subcat%type;
   label_text     dashboard.label_text%type;
   current_month  varchar2(13);
   ly_month       varchar2(13);
   ytd_tot        varchar2(13);
   lytd_tot       varchar2(13);
   ly_tot         varchar2(13);
begin
  for id in (/*iterate through the IDs*/) loop
   dashboard_package.visits(refCursorValue, id);
   loop
      fetch refCursorValue into cat, cat_order, subcat, label_text,
                                current_month, ly_month, ytd_tot,
                                lytd_tot, ly_tot;
      exit when refCursorValue%NOTFOUND;
      pipe row (visitobj (id, cat, cat_order, subcat, label_text,
                          current_month, ly_month, ytd_tot,
                          lytd_tot, ly_tot));
   end loop;
  end loop;
  return;
end test_refcur;

-- now you can simply do this:
SELECT * FROM TABLE(test_refcur);

(当然,“/*迭代 ID*/”将是您想要用来收集应调用函数的 ID 的任何方法 - 例如可以是 PL/SQL ID 表,或者可能是另一个查询)。

我再次强调,“一等奖”是根本不做任何额外的工作 - 只需使用一个 dashboard_package.visits 在一个 SQL 中完成所有工作。

顺便说一句,trim(to_char(sum(v.ly_tot),'9,999,999,999')) 可以简化为 to_char(sum(v.ly_tot),'FM9, 999,999,999')。此外,如果您使用'FM9G999G999G999' 格式,则它将不特定于区域设置。

关于oracle - 在 sys_refcursor 中使用 oracle 游标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1095183/

相关文章:

选择与表值函数连接中的 Oracle 标量函数

plsql - 返回序列 ID 列表的存储过程

cursors - TRS-80 POKE 光标表笑脸?

oracle - 在 SQL 数据库中存储一个范围/多个范围

MySQL 到 Oracle 语法错误(限制/偏移/更新)

java - 修改 PLSQL 函数以从同一列返回多行

oracle - 我可以在 Xquery 中使用用户定义的函数来替换 PLSQL 中的节点值吗?

oracle - 这就是非批量绑定(bind) PL/SQL 代码应如何转换为批量绑定(bind)代码的方式吗?是否有理由放弃 buk 绑定(bind)?

sql-server - SQL Server 游标引用(语法等)

python - 游标在 Python 的 DB-API 中是如何工作的?