2013-03-23 5 views
0

Я хочу, чтобы записи вставки/обновления записывались в другую таблицу (MICL_SUPERVISORS) с помощью Trigger (pl/sql oracle 10g).Ошибка уникального ограничения PL/SQL (INSERT/UPDATE) В триггере из-за sequencel.nextval

Когда Триггер он дает ошибку в

ORA-00001: ограничение уникальности нарушается.

Я знаю, что это происходит потому, что я хочу, чтобы добавить SUPID из последовательности

Select micl_sup_id_seq.nextval into nSUPID from dual 

И это происходит внутри цикла.

Подпись SUPID является основным ключом в моей таблице (MICL_SUPERVISOR). Поэтому я не могу отказаться от этого ограничения.

Как только я попытался автоинкремент, но это займет много времени, и это не сработало хорошо, и оно медленное. У меня есть тысячи записей в этой таблице. Я сделал это, как

SELECT MAX((SUP_ID)+1 from micl_sup_id_seq 

Из-за этой ошибки я сделал небольшое исследование и выяснили, что мы не можем использовать seq.nextval внутри триггера. Поэтому мой вопрос в том, есть ли простой и точный способ достичь этого?

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

CREATE OR REPLACE TRIGGER "c"."INSERT_MICL_SUP_DETAILS" 
AFTER INSERT OR UPDATE OF "ID","SUP_EMP_NO","EMP_NO" ON "MIMAX"."EMP" 
REFERENCING OLD AS "OLD" NEW AS "NEW" FOR EACH ROW 
DECLARE 
    miclaim_supervisor_count NUMBER; 
    employee_company_code VARCHAR2(10); 
    employee_businessunit NUMBER; 
    projmgr NUMBER; 
    nsupid NUMBER; 
CURSOR projmgrscursor IS 
SELECT b.bu_member_id 
    FROM bu_member b, emp_sub_div s 
WHERE s.emp_no = :NEW.emp_no 
    AND s.sub_division_code = '0345' AND s.div_code = '1010' 
    AND b.bu_id IN (SELECT bu_id FROM bu_member WHERE bu_member_id = :NEW.emp_no); 

BEGIN 
    DELETE 
    FROM micl_supervisors 
    WHERE emp_no = :NEW.emp_no 
    AND is_ovverridden = 0; 

    SELECT count(*) 
    INTO miclaim_supervisor_count 
    FROM micl_supervisors 
    WHERE emp_no = :NEW.emp_no 
    AND is_ovverridden = 1; 

    SELECT company_code 
    INTO employee_company_code 
    FROM employee_master 
    WHERE emp_no = :NEW.emp_no; 

    projmgr := 0; 
    IF (employee_company_code ='SOFT')THEN 
    OPEN projmgrscursor; 
    LOOP 
     FETCH projmgrscursor INTO projmgr; 
     EXIT WHEN projmgrscursor%notfound; 

     SELECT micl_sup_id_seq.nextval INTO nsupid FROM dual; 

     INSERT INTO micl_supervisors (sup_id,assigned_date 
            , assigned_by_emp_no 
            , amount_limit 
            , is_ovverridden 
            , sup_emp_no 
            , rtd_emp 
            , emp_no) 
           VALUES (nsupid 
            , SYSDATE 
            , :NEW.entryaddedby_emp_no 
            , 3000 
            , 0 
            , projmgr 
            , NULL 
            , :NEW.emp_no); 

    END LOOP; 
    CLOSE projmgrscursor; 
    ELSE 
    IF(miclaim_supervisor_count IS NULL OR miclaim_supervisor_count<1) THEN 
     INSERT INTO micl_supervisors VALUES (:NEW.ID 
              , SYSDATE 
              , :NEW.entryaddedby_emp_no 
              , 3000 
              , 0 
              , :NEW.sup_emp_no 
              , NULL 
              , :NEW.emp_no); 
    END IF; 
    END IF; 
END; 
/

Если что-то непонятно, спросите я также объясню этот сценарий, надеюсь, что кто-то поможет решить эту проблему

+0

Возможный дубликат [как вставить nextval для запуска внутри цикла] (http://stackoverflow.com/questions/15566087/how-to-insert-nextval-to-trigger-inside-for-loop). Вместо того, чтобы ставить один и тот же вопрос несколько раз, вернитесь назад и отредактируйте исходный вопрос. –

+0

ORA-00001: нарушение уникального ограничения возникает только тогда, когда вы пытаетесь вставить значение, которое уже находится в таблице micl_supervisors. Поэтому вы должны проверить: NEW.ID или уникальные столбцы ограничений отличаются от значений в таблице, когда вы запускаете триггер и последовательность nsupid, которую вы генерируете. – ajmalmhd04

+0

«... мы не можем использовать seq.nextval внутри триггера ...» - где вы это читали? –

ответ

1

Какие еще ограничения присутствуют на столе? Скорее всего, вы сталкиваетесь с ошибкой ограничения другой последовательности, на которую вы привязаны.

Из-за этой ошибки я сделал небольшое исследование и выяснил, что мы не можем использовать seq.nextval внутри триггера.

Я не знаю, где вы это читаете, но это абсолютно неверно. Я использовал seq.nextval для многих моих триггеров/таблиц аудита, и он отлично работает.

Запрос all_constraints (или user_constraints) с именем таблицы micl_supervisors - как так

SELECT * 
FROM user_constraints 
WHERE table_name = 'MICL_SUPERVISORS' 

и обновить вопрос или проверить с тем, что данные, которые вы пытаетесь вставить.

+0

спасибо за сообщение ур. Я сделал то, что сказал, но есть еще два ограничения, но его недостатки, связанные с этим Я отказываюсь от этого триггера, думая сделать это на уровне кода :) спасибо куча в любом случае спасибо большое – cHaNkX