Обработка уникальной ошибки ограничения и попытка автоматически сгенерировать уникальное значение до n раз, используя цикл - PullRequest
0 голосов
/ 07 сентября 2018

Я пытаюсь вставить автоматически сгенерированное значение в таблицу. Если возникает уникальная ошибка ограничения, я хочу получить новое значение и вставить последнее значение в таблицу. Я хочу попытаться сгенерировать уникальное значение до 10 раз, прежде чем выдать ошибку уникального ограничения.

Это то, что я имею до сих пор.

BEGIN
    autoGenValue := x
FOR i in 1..10 LOOP
    BEGIN
      INSERT INTO mainTbl(A,
                   B, 
                   C)
      VALUES(autoGenValue,
               b,
               c ) 
    EXCEPTION
          WHEN DUP_VAL_ON_INDEX
            THEN
                SELECT lpad(NVL(MAX(SUBSTR(A, -2)), '00')+1,4,'0')
                INTO maxSeq
                FROM RecvTbl

                SELECT car_id||maxSeq
                INTO autoGenValue 
                FROM DUAL;

         WHEN OTHERS THEN
             EXIT;          
     END;
   END LOOP;

    UPDATE RecvTbl
         SET A = autoGenValue 
         WHERE A = x;  
END;
COMMIT;      

x - это изначально рассчитанное автоматически сгенерированное значение, которое я пытаюсь вставить в mainTbl. Если есть уникальная ошибка ограничения, я следую некоторой требуемой логике (упрощенно здесь), чтобы получить требуемое уникальное значение. Я пробую это 10 раз (если требуется). Выйдите, когда не будет уникальной ошибки ограничения, и обновите recvTbl также значением, необходимым мне для будущих вычислений.

С моим кодом я заметил, что значение увеличивается после вставки в mainTbl, даже когда не было уникальной ошибки ограничения, и значение, вставленное в recvTbl, было увеличенным значением вместо значения в mainTbl.

Есть идеи, что я делаю не так?

1 Ответ

0 голосов
/ 07 сентября 2018

Проблема в том, что у вас нет выхода на успех .....

Вы выходите из цикла, если есть какая-либо ОШИБКА, отличная от DUP_VAL_ON_INDEX, но продолжаете цикл, если вставка прошла успешно.

Так что в следующий раз через цикл вы получите ошибку и приращение DUP_VAL_ON_INDEX.

Вы можете использовать что-то вроде ниже (не проверено), чтобы установить переменную успеха, а затем выйти из цикла, как только это правда.

BEGIN
autoGenValue := x;
v_success := false;
FOR i in 1..10 LOOP
    BEGIN
      INSERT INTO mainTbl(A,
                   B, 
                   C)
      VALUES(autoGenValue,
               b,
               c ) ;
      v_success := true;
    EXCEPTION
          WHEN DUP_VAL_ON_INDEX
            THEN
                SELECT lpad(NVL(MAX(SUBSTR(A, -2)), '00')+1,4,'0')
                INTO maxSeq
                FROM RecvTbl

                SELECT car_id||maxSeq
                INTO autoGenValue 
                FROM DUAL;

     WHEN OTHERS THEN
     EXIT;          
     END;
     if v_success = true then
       exit;
     end if;
   END LOOP;

    UPDATE RecvTbl
         SET A = autoGenValue 
         WHERE A = x;  
END;
COMMIT;      
...