如何根据编号插入记录。例如如果代码是 2 那么它应该将两条记录插入目标 table

How to insert records based on the number. For example If the code is 2 then it should insert two records into the target table

CREATE TABLE main_tab 
(
    seq_id      NUMBER(10),
    e_id        NUMBER(10),
    code        NUMBER(10),
    active_flg  NUMBER(1),
    CONSTRAINT pk_main_tab PRIMARY KEY(seq_id)
);

INSERT INTO main_tab VALUES(1,11,3,1);
INSERT INTO main_tab VALUES(2,22,2,1);

CREATE SEQUENCE transact_tab_sq;

CREATE TABLE transact_tab 
(
    seq_id NUMBER(10) DEFAULT transact_tab_Sq.NEXTVAL,
    e_id NUMBER(10),
    code        NUMBER(10),
    start_date  DATE,
    end_date    DATE,
    active_flg NUMBER(1),
    CONSTRAINT pk_transact_tab PRIMARY KEY(seq_id)
);

COMMIT;

使用的工具:SQL 开发人员 (18c)

我想将 main_tab table 中的行插入到 transact_tab table 中。假设 e_id = 11code 是 3,所以在 transact_tab table 中会有 4 条记录,代码为 0,1, 2 和 3,而 start_date 代码 3 的列将是今天的日期,代码 0 - 2 start_dateend_date 列将是今天的日期。

类似地,对于 e_id 22,其中 code 为 2,那么将有 3 条记录插入到 transact_tab 中,代码为 0,1 和 2,对于code 2 start_date 将是今天的日期,对于剩余的代码,即 1 start_dateend_date 两列都应该是今天的日期

预期输出:

+--------+------+------+------------+----------+------------+
| seq_id | e_id | code | start_Date | end_date | active_flg |
+--------+------+------+------------+----------+------------+
|      1 |   11 |    0 | 31-03-22   | 31-03-22 |          1 |
|      2 |   11 |    1 | 31-03-22   | 31-03-22 |          1 |
|      3 |   11 |    2 | 31-03-22   | 31-03-22 |          1 |
|      4 |   11 |    3 | 31-03-22   |          |          1 |
|      5 |   22 |    0 | 31-03-22   | 31-03-22 |          1 |
|      6 |   22 |    1 | 31-03-22   | 31-03-22 |          1 |
|      7 |   22 |    2 | 31-03-22   |          |          1 |
+--------+------+------+------------+----------+------------+

我的尝试:

SET SERVEROUTPUT ON;
DECLARE
lv_count NUMBER(10);
BEGIN
SELECT code INTO lv_count FROM main_tab;
IF lv_count > 1 THEN
    FOR i IN(SELECT * FROM main_tab)
    LOOP
    INSERT INTO transact_tab VALUES(seq_id,e_id,code,start_date,end_date,active_flag)
    SELECT transact_tab_sq.NEXTVAL,e_id,code,sysdate,sysdate,active_flg FROM main_tab;
    END LOOP;
END;

我不确定如何从 table 中获取代码并根据该代码插入记录

您需要两个循环:一个用于主 table 中的行,然后一个用于为该行创建的每个条目。

BEGIN
  FOR rec IN (SELECT * FROM main_tab) LOOP
    FOR i IN 1 .. rec.code LOOP
      INSERT INTO transact_tab
        (e_id, code, start_date, end_date, active_flag)
      VALUES 
        (rec.e_id, i, TRUNC(SYSDATE), CASE WHEN rec.code <> i THEN TRUNC(SYSDATE), rec.active_flag);
    END LOOP;
  END LOOP;
END;

你可能想也可能不想把 COMMIT 放在 PL/SQL 块内的某个地方。

这是 pl/sql

中的一种方法
DECLARE
BEGIN
  FOR r IN (SELECT * FROM main_tab) LOOP
    FOR i IN 1 .. r.code LOOP
      INSERT INTO transact_tab (e_id, code,start_date, end_date,active_flg)
        VALUES (r.e_id, i, SYSDATE, CASE WHEN i = r.code THEN NULL ELSE SYSDATE END, r.active_flg);
    END LOOP;
  END LOOP;
END;
/

根据评论更新: 我对同一个问题有一个疑问。假设明天 1-04-22 对于相同的 e_id 即存在 11 代码 5 那么我不需要打扰现有记录而是我将仅插入缺少的代码即 4 和 5 我将更新 end_date 的代码 3 到明天的日期,即 1-04-22,代码 4 和 5 的逻辑对于您已实现的 start_date 和 end_date 保持不变。这可能吗?

DECLARE 
  l_transact_row transact_tab%ROWTYPE;
BEGIN
  FOR r IN (SELECT * FROM main_tab) LOOP
    FOR i IN 1 .. r.code LOOP
      BEGIN
        SELECT * INTO l_transact_row 
          FROM transact_tab
         WHERE e_id = r.e_id AND code = i; 
        IF l_transact_row.end_date IS NULL AND i <> r.code THEN
          UPDATE transact_tab SET end_date = SYSDATE WHERE e_id = r.e_id AND code = i;
        END IF;
      EXCEPTION WHEN NO_DATA_FOUND THEN
        INSERT INTO transact_tab (e_id, code,start_date, end_date,active_flg)
          VALUES (r.e_id, i, SYSDATE, CASE WHEN i = r.code THEN NULL ELSE SYSDATE END, r.active_flg);  
      END ;
    END LOOP;
  END LOOP;
END;
/