需要处理PL/SQL BULK Collect For Loop中的IF条件

问题描述 投票:0回答:2

团队, 我有源表

SRC_TBL 
--------------  
STATUS EMP_ID
--------------
VALID   E1
VALID   E2
VALID   E3
VALID   E4
VALID   E5
VALID   E6
INVALID E7
INVALID E8
VALID   E9
VALID   E10
VALID   E11
VALID   E12
VALID   E13
VALID   E14
  1. 需要使用
    STATUS ='VALID'
    和 feed 表
    TAR_TBL
  2. 从 SRC_TBL 中挑选
  3. 将总有效记录分为批次,
    BATCH_ID
    ,每批次 5 条记录
  4. 此除法值
    5
    将作为参数传递。实际情况可以是每批次
    100 or 200
  5. 这里的样本数据很少。真实案例
    SRC_TBL
    表10000+条记录
  6. 因此需要以BULK COLLECT方式处理
  7. 但是在 BULK COLLECT 的 forallin 循环中不允许使用 IF/WHEN

TAR_TBL

STATUS  EMP_ID  BATCH_ID
VALID   E1      1
VALID   E2      1
VALID   E3      1
VALID   E4      1
VALID   E5      1
VALID   E6      2
VALID   E9      2
VALID   E10     2
VALID   E11     2
VALID   E12     2
VALID   E13     3
VALID   E14     3
sql plsql lookup bulk
2个回答
0
投票

这是您问题的代码。

DECLARE
  CURSOR c_src IS
    SELECT EMP_ID
    FROM SRC_TBL
    WHERE STATUS = 'VALID';

  TYPE emp_id_array IS TABLE OF SRC_TBL.EMP_ID%TYPE INDEX BY PLS_INTEGER;
  l_emp_ids emp_id_array;

  v_batch_size NUMBER := 5; -- You can change this to 100 or 200 based on your requirement.
  v_batch_id NUMBER := 1;

BEGIN
  OPEN c_src;

  LOOP
    FETCH c_src BULK COLLECT INTO l_emp_ids LIMIT v_batch_size;

    FORALL i IN 1..l_emp_ids.COUNT
      INSERT INTO TAR_TBL (STATUS, EMP_ID, BATCH_ID)
      VALUES ('VALID', l_emp_ids(i), v_batch_id);

    EXIT WHEN c_src%NOTFOUND;

    v_batch_id := v_batch_id + 1;
  END LOOP;

  CLOSE c_src;
END;
/

0
投票

无需 PL/SQL 代码,只需使用 SELECT 执行 INSERT 即可。使用

row_number()
窗口函数对行进行编号,并进行基本计算以获得每批 5 行。

select status, emp_id, trunc((rowno + 5 - 1) / 5) batch_id
from (
  select status, emp_id, row_number() over (order by status) rowno
  from src_tbl 
  where status = 'VALID'
) dt

将两个(!)5 替换为另一个数字以调整批量大小。

演示:https://dbfiddle.uk/jdifUOdo

© www.soinside.com 2019 - 2024. All rights reserved.