如何使用两个游标并显示它们 PL/SQL

Posted

技术标签:

【中文标题】如何使用两个游标并显示它们 PL/SQL【英文标题】:How to use two cursors and display them PL/SQL 【发布时间】:2017-08-02 13:56:23 【问题描述】:

我有一个问题并且找不到解决方案。上周我开始使用 PL/SQL,这意味着我的能力非常有限。

无论如何,我有一个工作脚本可以格式化表格以导出到另一个表格:

    select
        '7' as M_ID,
         N_PROT as SUBSCRIPTION_VERSION_ID,
      /* ..... bunch of other business logic */
    from N_TRANS
    where (CORA in ('0215','0320') or CORA in ('0215', '0320'))
    and N_PROT IS NOT null;

但是,它需要更改为仅搜索按 NUMBER (N_PROT) 分组的最后一个 ID (S_ID)。因此,我执行了另一个单独的脚本,通过 NUMBER (N_PROT) 从表中搜索最后一个 ID (S_ID) 组:

    declare
       cursor S_CURS IS
          select 
               max(S_ID) keep(dense_rank LAST order by N_PROT) S_ID,
               NR_PROTOCOLO
          from N_TRANS 
          group by N_PROT
          order by S_ID;

    S_HIST_T  S_CURS%ROWTYPE;
    type NTT_S_HIST_TRANS is table of S_HIST_T%type;
    LLL_S_HIST_TRANS NTT_S_HIST_TRANS;

    begin
       open  S_CURS;
       fetch S_CURS bulk collect into LLL_S_HIST_TRANS;
       close S_CURS;
       for indxx in 1..LLL_S_HIST_TRANS.count loop
          --The IDs as a var
          DBMS_OUTPUT.PUT_LINE(LLL_S_HIST_TRANS(indxx).S_HIST_T);
       end loop;
   end;

问题是我将如何加入这两个脚本。我想到的一种可能的解决方法是在第二个脚本 (¹) 的循环中执行第一个脚本。像这样的:

    declare
       cursor S_CURS IS
          select 
          ...     
    begin
      ... 
      for indxx in 1..LLL_S_HIST_TRANS.count loop
          --The IDs as a var
          select
             '7' as M_ID,
              N_PROT as SUBSCRIPTION_VERSION_ID,
              /* ..... bunch of other business logic */
          from N_TRANS
          where (CORA in ('0215','0320') or CORA in ('0215', '0320'))
          and N_PROT IS NOT null
          and S_ID = LLL_S_HIST_TRANS(indxx).S_HIST_T; -- (¹)
       end loop;
   end;

因此,以这种方式,我将如何保存内部 SELECT 并导出结果。我知道这不是一个好习惯,但我想不出更好的办法。 如果有人能给我一些关于如何解决这个问题的其他观点或帮助我解决我想出的这个解决方案,那就太好了!

为了解决问题,我已经启动并运行了一个脚本,我需要对其进行更改以执行相同的操作,但添加一个只能使用 LAST ID 的条件。我制作了一个能够获取 ID 并用光标隔离它们的脚本,现在,我必须将此 ID 合并到第一个脚本中。

谢谢!

【问题讨论】:

【参考方案1】:

如果您想将数据从一个表“导出”到另一个表并且您有选择,为什么不尝试使用“插入为选择”?

insert into your_new_table select <your_data> from N_TRANS where ...

【讨论】:

【参考方案2】:
begin
  for cv1 in (select
                  max(S_ID) keep(dense_rank LAST order by N_PROT) S_ID,              
                  NR_PROTOCOLO
                 from N_TRANS 
                 group by N_PROT
                 order by S_ID)
  loop
    for cv2 in (select
                '7' as M_ID,
                 N_PROT as SUBSCRIPTION_VERSION_ID,
                 /* ..... bunch of other business logic */
              from N_TRANS
              where (CORA in ('0215','0320') or CORA in ('0215', '0320'))
                and N_PROT IS NOT null
                and S_ID = cv1.S_ID)
    loop
      -- Processing logic here. To access either loop's data,
      -- prefix the column with cv1 or cv2, like cv2.M_ID, cv1.NR_PROTOCOLO
    end loop;  
  end loop;
end;

【讨论】:

【参考方案3】:

看起来你只需要这样的东西:

select m_id, n_prot, etc
from   ( select '7' as m_id
              , n_prot as subscription_version_id
              , /* ..... bunch of other business logic */
              , row_number() over(partition by n_prot order by s_id desc) as seq
         from   n_trans
         where  ( cora in ('0215', '0320') or cora in ('0215', '0320') )
         and    n_prot is not null )
where  seq = 1

【讨论】:

感谢您的回复,如果我不清楚,我很抱歉,但这不是我需要的。您编写的内部选择([...] select '7' as m_id ,n_prot as subscription_version_id [...])必须是外部选择,并且仅使用来自光标选择的 ID。 也许一些相同的数据和结果会使问题更清楚。以上是“每组最后一行”类型过滤的一般模式。

以上是关于如何使用两个游标并显示它们 PL/SQL的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Pl/SQL 中正确创建一个过程,在该过程中我创建一个表并使用一个游标

如何使用Oracle的游标?

PL/SQL-如何使用游标的所有列插入表

如何在 pl/sql 过程中使用游标返回多行和多列?

将新列添加到现有表中并使用 PL/SQL 中游标中的值更新它们

如何将游标添加到 PL/SQL 块中的过程中?