2017-05-30 178 views
-1

我必須創建一個觸發器來記錄購買表中的訂單號。將培訓數據庫和審計信息採購到AUDIT_TAB表中。這是書籍Christopher Allen的一項任務如何在PL/SQL上編寫功能強大且靈活的程序。創建觸發器ORACLE

CREATE TABLE audit 
(ORDER_NUMBER NUMBER(10), 
person_code   VARCHAR2(3), 
user_name  CHAR(30), 
user_machine  CHAR(20), 
change_in_quant  NUMBER(5), 
transaction_time DATE, 
FOREIGN KEY (person_code) REFERENCES persoon); 

CREATE SEQUENCE order_num_seq; 

CREATE OR REPLACE TRIGGER audit_trigger 
BEFORE INSERT OR UPDATE ON purchase 
FOR EACH ROW 
DECLARE 
no_name_change EXCEPTION; 
quant_change  NUMBER(5) := 0; 
BEGIN 

IF (UPDATING 
AND 
(:NEW.product_name <> :OLD.product_name)) 
THEN 
RAISE no_name_change; 
END IF; 

IF (((UPDATING) 
AND 
(:OLD.ORDER_NUMBER IS NULL)) 
OR 
((INSERTING) 
AND 
(:NEW.ORDER_NUMBER IS NULL))) 
THEN 
SELECT order_num_seq.NEXTVAL 
INTO :NEW.ORDER_NUMBER 
FROM dual; 
END IF; 


IF (UPDATING) 
THEN 
quant_change := :NEW. quantity - :OLD. quantity; 
ELSE 
quant_change := :NEW. quantity; 
END IF; 
INSERT INTO audit 
VALUES (:NEW.ORDER_NUMBER, 
    :NEW.salesperson, 
    USER, 
    USERENV ('TERMINAL') , 
    quant_change, 
    SYSDATE) ; 
EXCEPTION 
WHEN no_name_change 
THEN 
dbms_output.put_line ('Change of product name not allowed'); 
dbms_output.put_line ('Aborting and resetting to old values'); 
:NEW.product_name  := :OLD.product_name; 
:NEW. salesperson  := :OLD.salesperson; 
:NEW.ORDER_NUMBER := :OLD.ORDER_NUMBER; 
:NEW. quantity   := :OLD.quantity; 
END audit_trigger ; 
/

並且觸發器編譯時有警告。爲什麼?我的錯誤是什麼?

我的數據庫:

CREATE TABLE person ( 
person_code VARCHAR2(3) PRIMARY KEY,  
first_name VARCHAR2(15),  
last_name VARCHAR2(20),  
hire_date DATE  
); 
CREATE INDEX person_name_index  
ON person(last_name, first_name);  
ALTER TABLE person  
ADD CONSTRAINT person_unique UNIQUE ( 
first_name,  
last_name,  
hire_date  
);  
INSERT INTO person VALUES  
('CA', 'Charlene', 'Atlas', '01-ФЕВ-02'); 
INSERT INTO person VALUES  
('GA', 'Gary', 'Andersen', '15-ФЕВ-02'); 
INSERT INTO person VALUES  
('BB', 'Bobby', 'Barkenhagen', '28-ФЕВ-02');  
INSERT INTO person VALUES  
('LB', 'Laren', 'Baxter', '01-МАР-02 ');  
INSERT INTO person VALUES  
('LN', 'Linda', 'Norton', '01-ИЮН-03'); 

CREATE TABLE product (
product_name VARCHAR2(25) PRIMARY KEY, 
product_price NUMBER(4,2), 
quantity_on_hand NUMBER(5,0), 
last_stock_date DATE 
); 
ALTER TABLE product ADD (
CONSTRAINT positive_quantity CHECK(
quantity_on_hand IS NOT NULL 
AND 
quantity_on_hand >= 0) 
); 
INSERT INTO product VALUES 
('Small Widget', 99, 1, '15-ЯНВ-03'); 
INSERT INTO product VALUES 
('Medium Wodget', 75, 1000, '15-ЯНВ-02'); 
INSERT INTO product VALUES 
('Chrome Phoobar', 50, 100, '15-ЯНВ-03'); 
INSERT INTO product VALUES 
('Round Chrome Snaphoo', 25, 10000, null); 
INSERT INTO product VALUES 
('Extra Huge Mega Phoobar +', 9.95, 1234, '15-ЯНВ-04'); 
INSERT INTO product VALUES ('Square Zinculator', 
45, 1, TO_DATE ('Декабрь 31, 2002, 11:30', 
'Month dd, YYYY, HH:MI')); 
INSERT INTO product VALUES (
'Anodized Framifier', 49, 5, NULL); 
INSERT INTO product VALUES (
'Red Snaphoo', 1.95, 10, '31-ДЕК-01'); 
INSERT INTO product VALUES (
'Blue Snaphoo', 1.95, 10, '30-ДЕК-01'); 

CREATE TABLE purchase (
product_name VARCHAR2(25), 
salesperson VARCHAR2(3), 
purchase_date DATE, 
quantity NUMBER(4,2) 
); 
ALTER TABLE purchase 
ADD PRIMARY KEY (product_name, 
salesperson, 
purchase_date 
); 
ALTER TABLE purchase ADD (
CONSTRAINT reasonable_date CHECK(
purchase_date IS NOT NULL 
AND 
TO_CHAR(purchase_date, 'YYYY-MM-DD') >= '2000-06-30') 
); 
ALTER TABLE purchase 
ADD CONSTRAINT purchase_fk_product FOREIGN KEY 
(product_name) REFERENCES product; 
ALTER TABLE purchase 
ADD CONSTRAINT purchase_fk_person FOREIGN KEY 
(salesperson) REFERENCES person; 
CREATE INDEX purchase_product 
ON purchase(product_name); 
CREATE INDEX purchase_salesperson 
on purchase(salesperson); 
INSERT INTO purchase VALUES 
('Small Widget', 'CA', '14-ИЮЛ-03', 1); 
INSERT INTO purchase VALUES 
('Medium Wodget', 'BB', '14-ИЮЛ-03', 75); 
INSERT INTO purchase VALUES 
('Chrome Phoobar', 'GA', '14-ИЮЛ-03', 2); 
INSERT INTO purchase VALUES 
('Small Widget', 'GA', '15-ИЮЛ-03', 8); 
INSERT INTO purchase VALUES 
('Medium Wodget', 'LB', '15-ИЮЛ-03', 20); 
INSERT INTO purchase VALUES 
('Round Chrome Snaphoo', 'CA', '16-ИЮЛ-03', 5); 
INSERT INTO purchase VALUES 
('Small Widget', 'CA', '17-ИЮЛ-03', 1); 
CREATE TABLE purchase_archive (
product_name VARCHAR2 (25), 
salesperson VARCHAR2(3), 
purchase_date DATE, 
quantity NUMBER (4, 2) 
); 
INSERT INTO purchase_archive VALUES 
('Round Snaphoo', 'BB', '21-ИЮН-01', 10); 
INSERT INTO purchase_archive VALUES 
('Large Harflinger ' , 'GA', '22-ИЮН-01', 50); 
INSERT INTO purchase_archive VALUES 
('Medium Wodget', 'LB', '23-ИЮН-01', 20); 
INSERT INTO purchase_archive VALUES 
('Small Widget', 'ZZ', '24-ИЮН-02', 80); 
INSERT INTO purchase_archive VALUES 
('Chrome Phoobar', 'CA', '25-ИЮН-02', 2); 
INSERT INTO purchase_archive VALUES 
('Small Widget', 'JT', '26-ИЮН-02', 50); 
+0

什麼編譯錯誤? – APC

+0

@APC [link](https://yadi.sk/i/gs9fGRYK3JfQZN)僅限警告 –

+0

編譯警告是錯誤。請將它們作爲文本**張貼在這裏**。我沒有從一個未知的網站下載一些狡猾的圖片 – APC

回答

2

很少有錯誤,我可以看到。

1)您的Purchase表沒有您要在代碼中使用的ORDER_NUMBER列。添加該列和你的代碼應該可以工作。

2)Audit表的定義不正確。它引用一個不存在的表。 persoon表不存在。另外AUDIT是一個預留關鍵字,所以不應該使用它。

您可以檢查並重新編譯。

由於:OLD. quantity之間的空格而出現錯誤。查看代碼的工作版本。

CREATE OR REPLACE TRIGGER audit_trigger 
    BEFORE INSERT OR UPDATE 
    ON PURCHASE 
    FOR EACH ROW 
DECLARE 
    no_name_change EXCEPTION; 
    quant_change  NUMBER (5) := 0; 
BEGIN 
    IF (UPDATING AND (:NEW.product_name <> :OLD.product_name)) 
    THEN 
     RAISE no_name_change; 
    END IF; 

    IF ( ((UPDATING) AND (:OLD.ORDER_NUMBER IS NULL)) 
     OR ((INSERTING) AND (:NEW.ORDER_NUMBER IS NULL))) 
    THEN 
     SELECT order_num_seq.NEXTVAL INTO :NEW.ORDER_NUMBER FROM DUAL; 
    END IF; 


    IF (UPDATING) 
    THEN 
     quant_change := :NEW.quantity - :OLD.quantity; 
    ELSE 
     quant_change := :NEW.quantity; 
    END IF; 

    INSERT INTO audit1 
     VALUES (:NEW.ORDER_NUMBER, 
       :NEW.salesperson, 
       USER, 
       USERENV ('TERMINAL'), 
       quant_change, 
       SYSDATE); 
EXCEPTION 
    WHEN no_name_change 
    THEN 
     DBMS_OUTPUT.put_line ('Change of product name not allowed'); 
     DBMS_OUTPUT.put_line ('Aborting and resetting to old values'); 
     :NEW.product_name := :OLD.product_name; 
     :NEW.salesperson := :OLD.salesperson; 
     :NEW.ORDER_NUMBER := :OLD.ORDER_NUMBER; 
     :NEW.quantity := :OLD.quantity; 
END audit_trigger; 
/
+0

對不起,在這段代碼中我寫了persoon,但是在我的真實代碼中 - 我寫了'person',謝謝,我會試試 –

+0

請根據我的建議和你的代碼進行更改,如果這樣可以解決你的問題,通過接受解決方案來解決問題,\ – XING

+0

Okey,我會盡力的!謝謝你的回答 –