存储查询的输出,该查询在Oracle中的单个变量中返回多行

时间:2016-06-23 17:38:41

标签: oracle plsql cursor

Declare 
v_cardRecord card%ROWTYPE;
v_cardRecords IS TABLE OF card%ROWTYPE;
i BINARY_INTEGER;
Begin
select nt.name, nd.name, ct.name, ps.name, count(c.cardid) BULK COLLECT INTO v_cardRecords
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;

错误" PLS-00103,遇到" IS"当预计会出现以下情况之一。

2-之后,我想将v_cardRecords存储在另一个表中。

我该怎么办?

1 个答案:

答案 0 :(得分:0)

如果您只想从多个表中选择数据然后将结果插入另一个表中,那么就效率而言,最佳方法是

INSERT INTO <table_name>
(<column>
,<column>
)
SELECT
FROM
;

但是,如果您需要使用过程逻辑转换数据,那么批量处理肯定是可行的方法。由于多种原因,您的方法无效:

  1. 您正在批量收集不匹配的记录结构 您的查询
  2. 您的查询包含多个具有相同别名的列
  3. 批量收集中的语法错误
  4. 以下内容更接近您的要求:

    DECLARE 
    
      CURSOR C_get_cards
      IS
        SELECT 
         nt.name     nt_name
        ,nd.name     nd_name
        ,ct.name     ct_name
        ,ps.name     ps_name
        ,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
      ;
      TYPE cards_TAB_TYPE IS TABLE OF C_get_cards%ROWTYPE INDEX BY BINARY_INTEGER ;
      T_card_details              cards_TAB_TYPE ;
    
    BEGIN
      OPEN C_get_cards ;
    
      LOOP
    
        FETCH C_get_cards
          BULK COLLECT INTO T_card_details
          LIMIT 250
        ;
    
        FOR i IN 1..T_card_details.COUNT LOOP
          NULL ; 
          -- <transform / work on data here>  
        END LOOP ;
    
        FORALL i IN T_card_details.FIRST..T_card_details.LAST 
          INSERT INTO table_name
           (column1
           ,column2
           )
           VALUES
           (T_card_details(i).nt_name 
           ,T_card_details(i).nd_name 
           )
        ;
    
        EXIT WHEN T_card_details.COUNT = 0 ;
    
      END LOOP ;
    END ;