遍历游标并将游标的输出存储在另一个表中

Posted

技术标签:

【中文标题】遍历游标并将游标的输出存储在另一个表中【英文标题】:Iterate through cursor and storing the output of the cursor in another table 【发布时间】:2016-06-22 15:19:43 【问题描述】:

我正在尝试遍历存储表值的游标。我使用 FOR 循环进行迭代,如果满足其中一个条件,我将输出存储在另一个表中。我不确定我正在遵循的方法并且也收到错误(ORA-00933:SQL 命令未正确结束)。 Stats_Queries 是我在其中迭代光标的参考表。 STATS_RESULT_CARD 是我的输出表,我必须在其中存储结果。请帮忙。

 DECLARE
     CURSOR c1 IS
       select Stats_Queries.OBJECTTYPE, Stats_Queries.CATEGORY, Stats_Queries.QUERY  
       from Stats_Queries;
    r1 c1%ROWTYPE;
    BEGIN
      FOR r1 IN c1 LOOP
        If (r1.OBJECTTYPE = 'CARD') THEN
        INSERT INTO STATS_RESULTS_CARD (NODETYPENAME, NODEDEFNAME , CARDTYPENAME, PROVISIONSTATUSNAME, STATDATE, CARDCOUNT)
        select nt.name, nd.name, ct.name, ps.name, sysdate, count(c.cardid)
    from cardtype ct, card c, node n, nodetype nt, nodedef nd, provisionstatus ps
    where ct.name in ('SRA AMP', 'XLA AMP', 'SAM', 'ESAM')
    and ct.cardtypeid = c.card2cardtype
    and c.card2node = n.nodeid
    and n.node2nodetype = nt.nodetypeid
    and n.node2nodedef = nd.nodedefid
    and c.card2provisionstatus = ps.provisionstatusid
    group by nt.name, nd.name, ct.name, ps.name
    END If;
    END LOOP;
    END;

【问题讨论】:

游标和循环内的插入语句之间没有任何链接。因此,您要插入 X 个相同数据的副本,具体取决于游标中有多少行的对象类型为“CARD”(顺便说一句,为什么要在循环中而不是在游标本身中进行过滤?!)。这是你想要发生的事情吗? 【参考方案1】:

除了 Finbarr 提供的答案(这是完全正确的;添加缺少的分号,您的程序应该可以工作),为什么您需要遍历光标?这样做很慢。

您可以只执行一条插入语句,例如:

  insert into stats_results_card (nodetypename,
                                  nodedefname,
                                  cardtypename,
                                  provisionstatusname,
                                  statdate,
                                  cardcount)
    select x.nt_name,
           x.nd_name,
           x.ct_name,
           x.ps_name,
           x.statdate,
           x.cnt_cardid                               
    from   (select   nt.name nt_name,
                     nd.name nd_name,
                     ct.name ct_name,
                     ps.name ps_name,
                     sysdate statdate,
                     count (c.cardid) cnt_cardid
            from     cardtype ct,
                     card c,
                     node n,
                     nodetype nt,
                     nodedef nd,
                     provisionstatus ps
            where        ct.name in ('SRA AMP',
                                     'XLA AMP',
                                     'SAM',
                                     'ESAM')
                     and ct.cardtypeid = c.card2cardtype
                     and c.card2node = n.nodeid
                     and n.node2nodetype = nt.nodetypeid
                     and n.node2nodedef = nd.nodedefid
                     and c.card2provisionstatus = ps.provisionstatusid
            group by nt.name,
                     nd.name,
                     ct.name,
                     ps.name) x
           cross join (select stats_queries.objecttype,
                              stats_queries.category,
                              stats_queries.query
                       from   stats_queries
                       where  objecttype = 'CARD');

注意这假设原始光标和循环内的 select 语句之间确实没有任何链接;我们进行交叉连接以将行复制所需的次数。

如果两个查询之间存在实际连接,您可以用它代替交叉连接。

【讨论】:

【参考方案2】:
ORA-00933: SQL command not ended properly

可能是因为您在

后遗漏了一个分号
group by nt.name, nd.name, ct.name, ps.name

【讨论】:

以上是关于遍历游标并将游标的输出存储在另一个表中的主要内容,如果未能解决你的问题,请参考以下文章

将SP的输出游标合并到表中?

Sql Server在存储过程里面使用游标遍历一个表

mysql存储过程之游标遍历数据表

存储过程遍历更新

存储过程遍历更新

ORACLE 11G在存储过程里面遍历游标, 调用job任务定时运行