上記のように。 私は3つのテーブルがあると仮定します。DB2 SQL複数のトリガーカスケード
--table A, B, C
とカスケードに意図されている2つのトリガー:
--trigger X, Y
create trigger X
after insert on A
...(some codes)
update B set ...(some codes);
--and
create trigger Y
after update on B
...(some codes)
insert into C values (...(some codes));
:
--insert on A fire X to update B, then again fire Y to insert on C.
しかし、問題は、第1のトリガXは問題なく解雇されたであるが、第2のトリガYがされていません最初の後に発砲。
上記のコードにはどのような問題がありますか?
私のプロジェクトでは、すべてのエンティティをテストするためのミニウェアハウスデータベースを作成しています。以下は私がこれまで行ってきたコードです。私はのためのSQLCODEとSQLSTATEのドキュメントを読んで
--TRIGGER--
-------------------------------------------------------------------------------------------------------
--1)AUTO CREATE DELIVERY AFTER PLACING ORDER (no error)
CREATE TRIGGER REQUEST_DELIVERY
AFTER INSERT ON ORDER
REFERENCING NEW AS N
for each row mode db2sql
INSERT INTO DELIVERY VALUES (
DEFAULT,
N.ORDER_ID,
NULL
)@
--2)UPDATE STOCK QTY AFTER ISSUED A SUCCESSFUL DELIVERY (UPDATE DELIVERY WITH COURIER_ID MEANS PARCEL HAS
-- BEEN MAILED OUT)
--(error here, sqlstate="21000" & "09000",for trigger "...UPDATELOG)
drop trigger [email protected]
CREATE TRIGGER UPDATESTOCK_STOCKOUT
AFTER UPDATE OF COURIER_ID ON DELIVERY
REFERENCING OLD AS O
FOR EACH ROW MODE DB2SQL
BEGIN
UPDATE STOCK
SET STOCK_QTY = STOCK_QTY - (SELECT ORDER_QTY FROM ORDER WHERE ORDER.ORDER_ID = O.ORDER_ID)
WHERE STOCK_ID IN (SELECT STOCK_ID FROM ORDER WHERE ORDER.ORDER_ID = O.ORDER_ID);
[email protected]
--NOT WORKING EITHER FOR BELOW ALTERNATIVES--
----------------------------------------------------------------------------------------------
CREATE PROCEDURE UPDATEDELIVERY(IN ORD_ID DECIMAL(11,0), COU_ID DECIMAL(3,0))
BEGIN
UPDATE DELIVERY SET COURIER_ID = COU_ID WHERE ORDER_ID = ORD_ID;
--UPDATE STOCK SET STOCK_QTY = STOCK_QTY - (SELECT ORDER_QTY FROM ORDER WHERE ORDER.ORDER_ID = ORD_ID);
[email protected]
DROP PROCEDURE [email protected]
CREATE PROCEDURE UPDATEDELIVERY2(IN DLV_ID DECIMAL(11,0), COU_ID DECIMAL(3,0))
BEGIN
UPDATE DELIVERY SET COURIER_ID = COU_ID WHERE DELIVERY_ID = DLV_ID;
--UPDATE STOCK SET STOCK_QTY = STOCK_QTY - (SELECT ORDER_QTY FROM ORDER WHERE ORDER.ORDER_ID = (SELECT ORDER_ID FROM DELIVERY D WHERE D.DELIVERY_ID = DLV_ID))
--WHERE STOCK_ID = (SELECT STOCK_ID FROM ORDER O, DELIVERY D WHERE D.DELIVERY_ID = DLV_ID AND D.ORDER_ID = O.ORDER_ID);
[email protected]
---------------------------------------------------------------------------------------------
--3)auto update delivery.COURIER_ID once stock out in log
--(error here, sqlstate="21000" & "09000",for trigger "...UPDATELOG)
drop trigger [email protected]
CREATE TRIGGER UPDATELOG
AFTER UPDATE OF STOCK_QTY ON STOCK
REFERENCING OLD AS O
FOR EACH ROW MODE DB2SQL
BEGIN
IF O.STOCK_QTY < (SELECT STOCK_QTY FROM STOCK WHERE STOCK_ID = O.STOCK_ID) THEN
--STOCKIN
INSERT INTO LOG VALUES (
GENERATE_UNIQUE(),
'Stock-in',
((SELECT STOCK_QTY FROM STOCK WHERE STOCK_ID = O.STOCK_ID) - O.STOCK_QTY),
CURRENT DATE,
NULL,
O.STOCK_ID
);
--UPDATE STOCK
--SET STOCK_QTY = STOCK_QTY - (SELECT ORDER_QTY FROM ORDER WHERE ORDER.ORDER_ID = O.ORDER_ID AND ORDER.STOCK_ID = STOCK.STOCK_ID);
ELSEIF O.STOCK_QTY > (SELECT STOCK_QTY FROM STOCK WHERE STOCK_ID = O.STOCK_ID) THEN
--STOCKOUT
INSERT INTO LOG VALUES (
GENERATE_UNIQUE(),
'Stock-out',
(O.STOCK_QTY - (SELECT STOCK_QTY FROM STOCK WHERE STOCK_ID = O.STOCK_ID)),
CURRENT DATE,
(SELECT DELIVERY_ID FROM DELIVERY D, ORDER WHERE D.ORDER_ID = ORDER.ORDER_ID AND ORDER.STOCK_ID = O.STOCK_ID),
O.STOCK_ID
);
END IF;
[email protected]
カスケード層のために正しい順序で、
--INSERT INTO TABLE--
INSERT INTO VENUE VALUES (111,1,1)@
INSERT INTO VENUE VALUES (112,2,2)@
INSERT INTO VENUE VALUES (113,3,3)@
INSERT INTO CLIENT VALUES (DEFAULT,'ROAN','CHENG','60189774541','28 JLN APA')@
INSERT INTO CLIENT VALUES (DEFAULT,'AAA','ABC','601','29 JLJ AAA')@
INSERT INTO CLIENT VALUES (DEFAULT,'BBB','BBC','60111234567','30 JLN BBB')@
INSERT INTO COURIER VALUES (100,'DHL','EXP','60355006666')@
INSERT INTO COURIER VALUES (200,'ABX','EXP','60344007777')@
INSERT INTO COURIER VALUES (300,'POS','LAJU','61300882525')@
INSERT INTO STOCK VALUES (DEFAULT,'IPHONE 7','APPLE',100,111)@
INSERT INTO STOCK (STOCK_ID,STOCK_NAME,SUPPLIER_NAME,VENUE_ID) VALUES (10000001,'SAMSUNG S7','SAMSUNG',112)@
INSERT INTO STOCK VALUES (DEFAULT,'MMU','TM',300,113)@
INSERT INTO STOCK VALUES (DEFAULT,'CINEMA','TGV',200,111)@
INSERT INTO STOCK VALUES (DEFAULT,'FOO','FOOCORP',1000,113)@
INSERT INTO ORDER VALUES (DEFAULT,10,10000,10000003)@
INSERT INTO ORDER VALUES (DEFAULT,20,10000,10000002)@
INSERT INTO ORDER VALUES (DEFAULT,30,10002,10000002)@
とトリガー部:
--create tables, no error over here i assumed
CREATE TABLE VENUE(
VENUE_ID DECIMAL(3,0) NOT NULL CHECK (VENUE_ID BETWEEN 111 AND 333),
VENUE_FLOOR INT NOT NULL CHECK (VENUE_FLOOR IN (1,2,3)),
VENUE_SECTION INT NOT NULL CHECK (VENUE_SECTION IN (1,2,3)),
PRIMARY KEY (VENUE_ID)
)@
CREATE TABLE CLIENT(
CLIENT_ID DECIMAL(5,0) NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 10000 INCREMENT BY 1) CHECK (CLIENT_ID BETWEEN 10000 AND 99999),
CLIENT_FNAME VARCHAR(30) NOT NULL,
CLIENT_LNAME VARCHAR(30) NOT NULL,
CLIENT_PHONE VARCHAR(12) NOT NULL,
CLIENT_ADDRS VARCHAR(300) NOT NULL,
PRIMARY KEY (CLIENT_ID),
CONSTRAINT CLIENT_PHONE_UNQ UNIQUE (CLIENT_PHONE)
)@
CREATE TABLE COURIER(
COURIER_ID DECIMAL(3,0) NOT NULL CHECK (COURIER_ID BETWEEN 100 AND 999),
COURIER_FNAME VARCHAR(30) NOT NULL,
COURIER_LNAME VARCHAR(30) NOT NULL,
COURIER_PHONE VARCHAR(12) NOT NULL,
PRIMARY KEY (COURIER_ID),
CONSTRAINT COURIER_PHONE_UNQ UNIQUE (COURIER_PHONE)
)@
CREATE TABLE STOCK(
STOCK_ID DECIMAL(8,0) NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 10000000 INCREMENT BY 1) CHECK (STOCK_ID BETWEEN 10000000 AND 19999999),
STOCK_NAME VARCHAR(20) NOT NULL,
SUPPLIER_NAME VARCHAR(50) NOT NULL,
STOCK_QTY INT NOT NULL DEFAULT 0,
VENUE_ID DECIMAL(3,0) NOT NULL,
PRIMARY KEY (STOCK_ID),
FOREIGN KEY (VENUE_ID) REFERENCES VENUE ON DELETE no action,
CONSTRAINT STOCK_NAME_UNQ UNIQUE (STOCK_NAME),
CONSTRAINT SUPPLIER_NAME_UNQ UNIQUE (SUPPLIER_NAME)
)@
--CREATE TRIGGER/PROCEDURE CHECK STOCK_QTY - ORDER_QUANTITY >= 100--
CREATE TABLE ORDER(
ORDER_ID DECIMAL(11,0) NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 10000000000 INCREMENT BY 1) CHECK (ORDER_ID BETWEEN 10000000000 AND 99999999999),
ORDER_QTY INT NOT NULL CHECK (ORDER_QTY BETWEEN 10 AND 999),
CLIENT_ID DECIMAL(5,0) NOT NULL,
STOCK_ID DECIMAL(8,0) NOT NULL,
PRIMARY KEY (ORDER_ID),
FOREIGN KEY (CLIENT_ID) REFERENCES CLIENT(CLIENT_ID) ON DELETE no action,
FOREIGN KEY (STOCK_ID) REFERENCES STOCK(STOCK_ID) ON DELETE no action
)@
CREATE TABLE DELIVERY(
DELIVERY_ID DECIMAL(11,0) NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 16900000000 INCREMENT BY 1) CHECK (DELIVERY_ID BETWEEN 16900000000 AND 16999999999),
ORDER_ID DECIMAL(11,0) NOT NULL,
COURIER_ID DECIMAL(3,0),
PRIMARY KEY(DELIVERY_ID),
FOREIGN KEY(ORDER_ID)REFERENCES ORDER(ORDER_ID) ON DELETE no action,
FOREIGN KEY(COURIER_ID)REFERENCES COURIER(COURIER_ID) ON DELETE no action,
CONSTRAINT ORDER_ID_DELI_UNQ UNIQUE (ORDER_ID)
)@
--TO SELECT FOR LOG- USE SELECT TIMESTAMP(LOG_ID), ... FROM [email protected]
CREATE TABLE LOG(
LOG_ID CHAR(13) NOT NULL FOR BIT DATA,
LOG_PROCESS VARCHAR(9) NOT NULL CHECK (LOG_PROCESS IN ('Stock-in','Stock-out')),
LOG_QTY INT NOT NULL CHECK(LOG_QTY BETWEEN 10 AND 999),
LOG_DATE DATE NOT NULL,
DELIVERY_ID DECIMAL(11,0),
STOCK_ID DECIMAL(8,0) NOT NULL,
PRIMARY KEY(LOG_ID),
FOREIGN KEY(DELIVERY_ID)REFERENCES DELIVERY(DELIVERY_ID),
FOREIGN KEY(STOCK_ID)REFERENCES STOCK(STOCK_ID)
--CONSTRAINT DELIVERY_ID_LOG_UNQ UNIQUE (DELIVERY_ID)
)@
テストにいくつかの値を挿入エラーは、エラーがトリガーと1つ以上の値を返すいくつかのselectステートメントであると言います。
しかし、トリガ内のすべてのselect文(サブクエリとクエリ)をテストすると、エラーなしで動作する1つの値しか返されません。
ERROR:
An error occurred in a triggered SQL statement
in trigger "PCNAME.UPDATELOG".
Information returned for the error includes SQLCODE "-811",
SQLSTATE "21000" and message token "", SQLSTATE "09000"
PS:説明で正しいことを行うために私を案内する代わりに、私はちょうど簡単な答えを与えることによって、私を助けてください、私の脳は、このSQLトラフィックに捕まってしまいました。私がこのレッスンから何かを学ぶことができなければ、私は正式に運命に陥っています。
これはコードの実際の問題かもしれませんが、私は最初に試してみる必要があります、ありがとうございます。ところで、カスケードするための3つのダミーテーブル(各テーブルに2つの列を持つA、B、C)と2つのトリガー(X、Y、X火Y)を作成しようとしました。しかし、それは私が期待している方法ではうまくいかない。 –
これは私のコードではまさにエラーですので、もう一度ありがとうございます。一時的に一時テーブルtempを作成し、UPDATELOGトリガーで使用するDELIVERYテーブルの一意のORDER_IDを一時的に保存しました。 –