我试图制作一个触发器,阻止您将新的Bill Item插入" Bill_Item"如果该法案已经支付,则为表格。比尔表中有一个Paid_YN和一个Posted_YN列。因此,根据您要添加的帐单,如果已付款或过帐,则会拒绝该帐单。我的更新和删除部分在此代码中工作,但不是"插入"部分。请帮忙!我抱歉没有缩进,无法正确复制代码。 请让我知道我哪里错了!这是我的逻辑吗?我已经尝试谷歌搜索并在这里搜索错误消息,但仍然无法弄明白!
TABLES ::
CREATE TABLE Bill (
Bill_Number NUMBER (6,0)
CONSTRAINT Bill_pk PRIMARY KEY
CONSTRAINT Bill_Number_NN NOT NULL,
Bill_Date DATE DEFAULT SYSDATE
CONSTRAINT Bill_Date_NN NOT NULL,
Waiter_Number NUMBER (5,0)
CONSTRAINT Bill_Waiter_Number_FK REFERENCES Waiter (Waiter_Number)
CONSTRAINT Bill_Waiter_Number_NN NOT NULL,
Table_Number NUMBER (2,0)
CONSTRAINT Bill_Table_Number_NN NOT NULL,
Customer_Count NUMBER (2,0) DEFAULT 1
CONSTRAINT Bill_Customer_Count_CK CHECK (Customer_Count > 0)
CONSTRAINT Bill_Customer_Count_NL NULL,
Paid_YN CHAR (1) DEFAULT 'N'
CONSTRAINT Bill_Paid_YN_CK CHECK ((Paid_YN = 'Y') OR (Paid_YN = 'N'))
CONSTRAINT Bill_Paid_YN_NN NOT NULL,
Posted_YN CHAR (1) DEFAULT 'N'
CONSTRAINT Bill_Posted_YN_CK CHECK ((Posted_YN = 'Y') OR (Posted_YN = 'N'))
CONSTRAINT Bill_Posted_YN_NN NOT NULL,
Bill_GST NUMBER (6,2) DEFAULT 0
CONSTRAINT Bill_GST_CK CHECK (Bill_GST >= 0)
CONSTRAINT Bill_GST_NN NOT NULL,
Bill_Total NUMBER (8,2) DEFAULT 0
CONSTRAINT Bill_Total_CK CHECK (Bill_Total >= 0)
CONSTRAINT Bill_Total_NN NOT NULL
);
CREATE TABLE Bill_Item (
Bill_Number NUMBER (6,0)
CONSTRAINT BItem_Bill_Number_FK REFERENCES Bill (Bill_Number)
CONSTRAINT BItem_Bill_Number_NN NOT NULL,
Menu_Item_Number NUMBER (5,0)
CONSTRAINT BItem_Menu_Item_Number_FK REFERENCES Menu_Item (Menu_Item_Number)
CONSTRAINT BItem_Menu_Item_Number_NN NOT NULL,
Discount NUMBER (5,2) DEFAULT 0
CONSTRAINT BItem_Discount_CK CHECK ((Discount >= 0 ) AND (Discount <= 100))
CONSTRAINT BItem_Discount_NL NULL,
Quantity_Sold NUMBER (3,0) DEFAULT 1
CONSTRAINT BItem_Quantity_Sold_CK CHECK (Quantity_Sold > 0)
CONSTRAINT BItem_Quantity_Sold_NN NOT NULL,
Selling_Price NUMBER (6,2) DEFAULT 0
CONSTRAINT BItem_Selling_Price_CK CHECK (Selling_Price >= 0)
CONSTRAINT BItem_Selling_Price_NN NOT NULL,
CONSTRAINT Bill_Item_PK PRIMARY KEY (Bill_Number, Menu_Item_Number)
);
触发::
CREATE OR REPLACE TRIGGER TR_Q5
BEFORE
UPDATE OR
INSERT OR
DELETE ON
BILL_ITEM
FOR EACH ROW
DECLARE
v_Paid_YN CHAR(1);
v_Posted_YN CHAR(1);
BEGIN
IF UPDATING THEN
SELECT Paid_YN, Posted_YN
INTO v_paid_YN, v_Posted_Yn
FROM Bill
WHERE Bill_Number = :OLD.Bill_Number;
IF v_Paid_YN = 'Y' AND
v_Posted_YN = 'N' THEN
RAISE_APPLICATION_ERROR(-20001, 'Cannot update the bill once its been paid!');
END IF;
IF v_Posted_YN = 'Y' AND
v_Paid_YN = 'N' THEN
RAISE_APPLICATION_ERROR(-20002, 'Cannot update the bill once its been posted!');
END IF;
IF v_Paid_YN = 'Y' AND
v_Posted_YN = 'Y' THEN
RAISE_APPLICATION_ERROR(-20003, 'Cannot update the bill once its been paid and posted!');
END IF;
ELSIF INSERTING THEN
SELECT Paid_YN, Posted_YN
INTO v_paid_YN, v_Posted_Yn
FROM Bill
WHERE Bill_Number = :OLD.Bill_Number;
IF v_Paid_YN = 'Y' AND
v_Posted_YN = 'N' THEN
RAISE_APPLICATION_ERROR(-20004, 'Cannot add to the bill once its been paid!');
END IF;
IF v_Posted_YN = 'Y' AND
v_Paid_YN = 'N' THEN
RAISE_APPLICATION_ERROR(-20005, 'Cannot add to the bill once its been posted!');
END IF;
IF v_Paid_YN = 'Y' AND
v_Posted_YN = 'Y' THEN
RAISE_APPLICATION_ERROR(-20006, 'Cannot add to the bill once its been paid and posted!');
END IF;
ELSIF DELETING THEN
SELECT Paid_YN, Posted_YN
INTO v_paid_YN, v_Posted_Yn
FROM Bill
WHERE Bill_Number = :OLD.Bill_Number;
IF v_Paid_YN = 'Y' AND
v_Posted_YN = 'N' THEN
RAISE_APPLICATION_ERROR(-20007, 'Cannot delete from the bill once its been paid!');
END IF;
IF v_Posted_YN = 'Y' AND
v_Paid_YN = 'N' THEN
RAISE_APPLICATION_ERROR(-20008, 'Cannot delete from the bill once its been posted!');
END IF;
IF v_Paid_YN = 'Y' AND
v_Posted_YN = 'Y' THEN
RAISE_APPLICATION_ERROR(-20009, 'Cannot delete from the bill once its been paid and posted!');
END IF;
END IF;
END TR_Q5;
/
SHOW ERRORS;
AND此插入返回:
Insert Into Bill_Item
(Bill_Number, Menu_Item_Number, Discount, Quantity_Sold, Selling_Price)
Values
(4945, 2, 0, 1, 1.03);
Error starting at line : 234 in command -
Insert Into Bill_Item
(Bill_Number, Menu_Item_Number, Discount, Quantity_Sold, Selling_Price)
Values
(4945, 2, 0, 1, 1.03)
Error report -
SQL Error: ORA-01403: no data found
ORA-06512: at "ORCL1_05.TR_Q5", line 24
ORA-04088: error during execution of trigger 'ORCL1_05.TR_Q5'
01403. 00000 - "no data found"
*Cause: No data was found from the objects.
*Action: There was no data from the objects which may be due to end of
fetch.
答案 0 :(得分:2)
这是你的大事:
ELSIF INSERTING THEN
SELECT Paid_YN, Posted_YN
INTO v_paid_YN, v_Posted_Yn
FROM Bill
WHERE Bill_Number = :OLD.Bill_Number;
在INSERT期间,:old
命名空间为空。这是完全符合逻辑的:我们正在插入记录,旧记录还有什么其他内容?
所以解决方案很简单
ELSIF INSERTING THEN
SELECT Paid_YN, Posted_YN
INTO v_paid_YN, v_Posted_Yn
FROM Bill
WHERE Bill_Number = :NEW.Bill_Number;
在UPDATING和DELETING时, :old
有效,这就是这些分支工作的原因。 (通常在UPDATING时测试当前 - :new
- 值,除非检查值是否已更改。)