【问题标题】:FORALL Bulk Collect - Need to add a sequence to insert statement without using a loop?FORALL Bulk Collect - 需要在不使用循环的情况下添加插入语句的序列?
【发布时间】:2018-05-09 13:38:45
【问题描述】:

所以我有一个 FORALL 大容量集合,用于将值插入到表中。

通常我会为必须填充的序列字段使用循环。例子是这样的............

seqno = seqno +1

.....然后我会循环遍历每条记录,因为它们会在插入时增加 1。

SELECT bis_part, bis_part_org, bis_store, bis_bin, bis_lot, bis_qty
BULK COLLECT INTO V_STTK_CLTN 
FROM table1
WHERE bis_bin = 'DIRECT'
AND bis_store = p_org;


FORALL INDX IN 1 .. V_STTK_CLTN.COUNT 

  INSERT INTO table2
   (stl_part,
    stl_part_org,
    stl_trans,
    stl_store,
    stl_bin,
    stl_lot,
    stl_expqty,
    stl_phyqty,
    stl_rtype,
    stl_type,
    stl_line ) 
   VALUES
   (V_STTK_CLTN(INDX).bis_part,
    V_STTK_CLTN(INDX).bis_part_org,
    ctrans,
    V_STTK_CLTN(INDX).bis_store,
    V_STTK_CLTN(INDX).bis_bin,
    V_STTK_CLTN(INDX).bis_lot,
    V_STTK_CLTN(INDX).bis_qty,
    '',
    'STTK',
    'STTK',
     seqno);

既然我使用的是没有循环的 FORALL,我怎么能对集合执行此操作?

seqno 值是我需要序列的地方。每次运行时,它都会将这些记录插入到同一个表中,但序列每次都必须从一个开始,因为它是集合而不是整个表的序列......有意义吗?

【问题讨论】:

  • 创建一个序列并使用它。 SEQ_X.nexval? docs.oracle.com/cd/B28359_01/server.111/b28286/…
  • seqno 列是您从中驱动 FORALL 语句的集合的属性吗?更实际的代码会让我们更清楚您的场景。
  • 在要插入的表上使用序列,还是在 12c 以后使用 IDENTITY 列? (以便接收表负责创建/管理您的顺序值。)
  • 您好,感谢大家的帮助......我添加了一些代码来向您展示我正在使用的内容。我正在使用一个循环,只是循环遍历记录,但我现在必须使用 FORALL 插入......不允许循环。这甚至可能吗?我想用 ROWNUM 代替变量 seqno 但我得到这个错误.....ORA-00976: Specified pseudocolumn or operator not allowed here.
  • 检查我的答案并接受它有帮助的答案。另请阅读:stackoverflow.com/help/someone-answers

标签: sql oracle plsql bulk-collect


【解决方案1】:

很简单

创建一个序列

CREATE SEQUENCE seq;

假设您要插入表格t

create table t(id INT, rowname VARCHAR2(20));

此块将在FORALL 块中插入一些虚拟行,并将使用一个序列。而不是你的循环,从SELECT查询或CURSOR批量收集到一个集合中

DECLARE 
    TYPE ctype 
      IS TABLE OF t%ROWTYPE; 
    ct ctype; 
BEGIN 
    SELECT seq.NEXTVAL AS id, 
           'ROW' 
           ||LEVEL     AS rowname 
    bulk   collect INTO ct 
    FROM   dual 
    CONNECT BY LEVEL <= 100; 

    forall i IN ct.first..ct.last 
      INSERT INTO t 
      VALUES ct(i); 
END; 

/ 

Db fiddle演示

【讨论】:

    【解决方案2】:

    正如其他人所提到的,也许序列是满足用例要求的最佳方法。

    但要严格回答您关于如何使用 FORALL 语句复制递增计数器变量的问题,您可以执行以下操作:

    L_OFFSET := 0;
    
    FORALL INDX IN 1 .. V_STTK_CLTN.COUNT 
      INSERT INTO table2
       (stl_part,
        stl_part_org,
        stl_trans,
        stl_store,
        stl_bin,
        stl_lot,
        stl_expqty,
        stl_phyqty,
        stl_rtype,
        stl_type,
        stl_line ) 
       VALUES
       (V_STTK_CLTN(INDX).bis_part,
        V_STTK_CLTN(INDX).bis_part_org,
        ctrans,
        V_STTK_CLTN(INDX).bis_store,
        V_STTK_CLTN(INDX).bis_bin,
        V_STTK_CLTN(INDX).bis_lot,
        V_STTK_CLTN(INDX).bis_qty,
        '',
        'STTK',
        'STTK',
         L_OFFSET+INDX);
    

    通过这种方式,您可以将 L_OFFSET 设置为初始偏移量,并让 INDX 为集合中的每条记录增加一次。

    【讨论】:

      【解决方案3】:

      所以我只需要在集合的记录中添加一个数字列。

       TYPE STTK_RECORD IS RECORD(
      

      BIS_PART T1.BIS_PART%TYPE ,BIS_PART_ORG T1.BIS_PART_ORG%TYPE ,BIS_STORE T1.BIS_STORE%TYPE ,BIS_BIN T1.BIS_BIN%TYPE ,BIS_LOT T1.BIS_LOT%TYPE ,BIS_QTY T1.BIS_QTY%TYPE ,RN 编号 );

      然后我将 row_number 函数添加到批量收集的 select 语句中:

      SELECT bis_part, bis_part_org, bis_store, bis_bin, bis_lot, bis_qty, ROW_NUMBER() OVER (PARTITION BY bis_store ORDER BY bis_bin desc) RN
      

      批量收集到 V_STTK_CLTN;

      最后我插入了新列:

      FORALL INDX IN V_STTK_CLTN.FIRST .. V_STTK_CLTN.LAST
      
        INSERT INTO T2
         (stl_part,
          stl_part_org,
          stl_trans,
          stl_store,
          stl_bin,
          stl_lot,
          stl_expqty,
          stl_phyqty,
          stl_rtype,
          stl_type,
          stl_line ) 
         VALUES
         (V_STTK_CLTN(INDX).bis_part,
          V_STTK_CLTN(INDX).bis_part_org,
          ctrans,
          V_STTK_CLTN(INDX).bis_store,
          V_STTK_CLTN(INDX).bis_bin,
          V_STTK_CLTN(INDX).bis_lot,
          V_STTK_CLTN(INDX).bis_qty,
          '',
          'STTK',
          'STTK',
          V_STTK_CLTN(INDX).rn);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-08
        • 2020-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-10
        相关资源
        最近更新 更多