プロが教える店舗&オフィスのセキュリティ対策術

お世話になります。
今回、あるTBL1のフィールド:[氏名]を入力すると同テーブルのフィールド:[社員番号]が自動で
セットされるようなトリガーを作成しようとおもっています。
しかし、変更表の更新には複合トリガーを使用しなければ出来ないというのはわかったのですが、
うまいことコンパイルできません。下記に前提条件と自分なりに作成したトリガーをを記載しますので
どなたか助けてください。

<前提条件>
・セットされる社員番号はプライマリーキーとなっている。
・更新される条件はTBL1のフィールド:[データ区分]が2or3のとき

<作成したトリガー>


CREATE OR REPLACE TRIGGER TRG_SET_AUTO_SHAIN_NO
FOR INSERT ON CM_PORTAL_SHAIN
COMPOUND TRIGGER
REFERENCING OLD AS OLD NEW AS NEW
WHEN (NEW.DATA_KBN in (2,3))
DECLARE

GRP_CD VARCHAR2(3);
SEQ_NO NUMBER(4);
NEW_SET_NO VARCHAR2(7);

AFTER STATEMENT IS
BEGIN
IF :NEW.DATA_KBN = 2 THEN
select SQ.GROUP_CD,SQ.SEQUENCE_NO + 1 into GRP_CD,SEQ_NO
from CM_HAKEN_GROUP_SEQUENCE_MT SQ where SQ.GROUP_CD = '999';
ELSE
select SQ.GROUP_CD,SQ.SEQUENCE_NO + 1 into GRP_CD,SEQ_NO
from CM_HAKEN_GROUP_SEQUENCE_MT SQ where SQ.GROUP_CD = '888';
END IF;

NEW_SET_NO := substr(GRP_CD,LPAD(SEQ_NO,4,0));

INSERT INTO CM_PORTAL_SHAIN (SHAIN_NO,SHIMEI_LOCAL,DATA_KBN) VALUES (NEW_SET_CD,:NEW.SHIMEI_LOCAL,:NEW.DATA_KBN);

AFTER EACH ROW IS
BEGIN

INSERT INTO CM_PORTAL_SHAIN (SHAIN_NO) VALUES (NEW_SET_NO)

END;
/

ちなみにこれでコンパイルするとエラーが発生します・・・
どこがいけないのでしょうか?

A 回答 (2件)

複合トリガーについては理解できていないのですが、質問の内容でも必要なのでしょうか。


>あるTBL1のフィールド:[氏名]を入力すると同テーブルのフィールド:[社員番号]が自動でセットされるようなトリガー
だけなら、普通のトリガーでいいと思うのですが。

たとえば、

CREATE OR REPLACE TRIGGER TRG_SET_AUTO_SHAIN_NO
BEFORE INSERT ON CM_PORTAL_SHAIN
FOR EACH ROW
WHEN (NEW.DATA_KBN in (2,3))
DECLARE

GRP_CD VARCHAR2(3);
SEQ_NO NUMBER(4);
NEW_SET_NO VARCHAR2(7);

BEGIN
IF :NEW.DATA_KBN = 2 THEN
GRP_CD := '999';
ELSE
GRP_CD := '888';
END IF;

--社員番号はグループごとに連番で振りたいということですよね?
--質問文のコードでは連番取得後にテーブルの更新処理をしていないですが必要じゃないですか?
--実際にはSEQUENCEを使った方がいいような気がします
select SQ.GROUP_CD,SQ.SEQUENCE_NO + 1 into GRP_CD,SEQ_NO
from CM_HAKEN_GROUP_SEQUENCE_MT SQ where SQ.GROUP_CD = GRP_CD for update;
update CM_HAKEN_GROUP_SEQUENCE_MT set sequence_no = seq_no
where GROUP_CD = GRP_CD;

--SHAIN_NOに値を設定するだけで、トリガー内でINSERTやUPDATEを発行する必要はない
--質問では、NEW_SET_NO := substr(GRP_CD,LPAD(SEQ_NO,4,0)); となっていましたが
--本当は連結するのだろうと勝手に想像しました。
:new.SHAIN_NO := GRP_CD || LPAD(SEQ_NO,4,'0');
end;
/

こんな感じでも。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
まさに言われてとおりです!
というかソースをそのまま書いたらうまくいきました!
シーケンスの更新部分も必要な箇所でしたので考慮頂き非常に助かりました。
こんなスマートな方法があったんですね。
大変勉強になりました。
本当にありがとうございます。

お礼日時:2011/11/21 17:15

今、検証する環境が手元にないのですが、


http://otndnld.oracle.co.jp/document/products/or …
を見る限り
・複合トリガーにDECLARE宣言はない
・各トリガーのセクション(AFTER STATEMENT IS BEGIN で始まる)は「ND AFTER STATEMENT」で終わっている。
などが気になります。

この回答への補足

ご回答ありがとうございます。

頂いたリンクから例文を参照しましたが、
FOR INSERTの部分で構文エラーが発生しているようです。
例文をそのまま実行してみてもFORの部分でエラーが発生します。
この部分はAFTER、BEFORE、INSTEAD OFを指定しなければいけないのでしょうか?

補足日時:2011/11/21 12:14
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す