在下面插入代码时违反了唯一约束消息

Unique constraint violated message on inserting code below

我正在编写这段代码,它在主键中引发错误:

DECLARE CURSOR A1 AS
    SELECT 
        TRANS_DET_ID,
        (SELECT MAX (NVL(TRANS_DET_DET_ID, 0) + 1)
         FROM PROD_OPERATIONS_RATE) DET_ID,
        OPER_CODE, ART_CODE, RATE, FROM_DATE, CLOSE_IND 
    FROM 
        PROD_OPERATIONS_RATE
    WHERE 
        TRANS_DET_ID = 1
        AND OPER_CODE = 1
        AND RATE = 2.3005;

a1_var A1%ROWTYPE;
 BEGIN
    
    OPEN A1;
    LOOP
      FETCH A1
        INTO a1_var;
      EXIT WHEN A1%NOTFOUND;
    
      INSERT INTO PROD_OPERATIONS_RATE (
        TRANS_DET_ID,TRANS_DET_DET_ID,OPER_CODE,ART_CODE,RATE,FROM_DATE,CLOSE_IND)
        VALUES (1,a1_var.DET_ID,1,a1_var.ART_CODE,2.50,DATE '2022-05-01','N');
    END LOOP;
    CLOSE A1;
    COMMIT;
 END;

我想插入相同的数据 table 满足抛出条件,它抛出主键列 TRANS_DET_DET_ID 上唯一约束的错误。我究竟做错了什么?请问有人可以帮我吗?问候

计算为 MAX + 1 的唯一(主)键值几乎总是错误的。切换到序列。

查找最大值 trans_det_det_id 值:

SELECT MAX (trans_det_det_id) max_id FROM PROD_OPERATIONS_RATE;

将序列创建为 max_id + 1(我将 虚拟 值设置为 1000;您实际上会使用什么查询 returns):

CREATE SEQUENCE seq START WITH 1000;    

现在,在您的 PL/SQL 脚本中使用序列:

DECLARE
   CURSOR A1 IS
      SELECT TRANS_DET_ID,
             --(SELECT MAX (NVL (TRANS_DET_DET_ID, 0) + 1)
             --   FROM PROD_OPERATIONS_RATE) DET_ID,
             OPER_CODE,
             ART_CODE,
             RATE,
             FROM_DATE,
             CLOSE_IND
        FROM PROD_OPERATIONS_RATE
       WHERE     TRANS_DET_ID = 1
             AND OPER_CODE = 1
             AND RATE = 2.3005;

   a1_var  A1%ROWTYPE;
BEGIN
   OPEN A1;

   LOOP
      FETCH A1 INTO a1_var;

      EXIT WHEN A1%NOTFOUND;

      INSERT INTO PROD_OPERATIONS_RATE (TRANS_DET_ID,
                                        TRANS_DET_DET_ID,
                                        OPER_CODE,
                                        ART_CODE,
                                        RATE,
                                        FROM_DATE,
                                        CLOSE_IND)
           VALUES (1,
                   seq.NEXTVAL,     -- a1_var.DET_ID,
                   1,
                   a1_var.ART_CODE,
                   2.50,
                   DATE '2022-05-01',
                   'N');
   END LOOP;

   CLOSE A1;

   COMMIT;
END;

顺便说一句,如果没有特别的理由在循环中慢慢,使用普通的INSERT INTO语句(SQL,而不是PL/SQL),它会快很多

INSERT INTO prod_operations_rate (trans_det_id,
                                  trans_det_det_id,
                                  oper_code,
                                  art_code,
                                  rate,
                                  from_date,
                                  close_ind)
   SELECT trans_det_id,
          seq.NEXTVAL,
          oper_code,
          art_code,
          rate,
          from_date,
          close_ind
     FROM prod_operations_rate
    WHERE     trans_det_id = 1
          AND oper_code = 1
          AND rate = 2.3005;