0

トリガー(pl / sql oracle 10g)を使用して、レコードを別のテーブル(MICL_SUPERVISORS)に挿入/更新したい。

トリガーが起動すると、次のようなエラーが発生します

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を使用できないことがわかりました。だから私の質問は、これを達成するための簡単で正確な方法はありますか?

これがコードです(if句else部分が正常に機能している場合はすべて内部で発生します。カーソルを使用していることに注意してください。開いているカーソル内でこれがすべて発生します)

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;
/

不明な点がある場合は、このシナリオについてさらに説明します。誰かがこの問題の解決に役立つことを願っています。

4

1 に答える 1

1

テーブルには他にどのような制約がありますか? 固執しているシーケンス以外の制約エラーが発生している可能性が高くなります。

このエラーのため、ちょっとした調査を行ったところ、トリガー内で seq.nextval を使用できないことがわかりました。

あなたがどこでそれを読んだかはわかりませんが、それは完全に誤りです。多くの監査トリガー/テーブルに seq.nextval を使用しましたが、正常に動作します。

テーブル名でクエリall_constraints(または) - のようにuser_constraintsmicl_supervisors

SELECT *
FROM   user_constraints
WHERE  table_name = 'MICL_SUPERVISORS' 

質問を更新するか、挿入しようとしているデータを確認してください。

于 2013-03-26T14:12:46.453 に答える