2015-05-05 32 views
0

後,我試圖更新列在我的子表service對父表cars刪除使用功能choose_ideal_car其中超過carsservice表使用了一些選擇之後。ORACLE SQL-對父表刪除觸發器與級聯組空,變異錯誤的解決方法

這裏是我的SQL腳本的一部分:

CREATE TABLE cars(car_id INT CONSTRAINT pk_id_cars); 
CREATE TABLE service(
service_id INT CONSTRAINT pk_id_service PRIMARY KEY, 
car_id INT CONSTRAINT fk_id_car REFERENCES cars(car_id) ON DELETE SET NULL, 
period VARCHAR2(5) CONSTRAINT check_period CHECK period IN ('even','odd','every'), 
period VARCHAR2(3) CONSTRAINT check_day CHECK day IN ('mon','tue','wed','thu','fri') 
); 
CREATE OR REPLACE TRIGGER service_set_car_id AFTER DELETE ON cars 
DECLARE 
CURSOR touched_rows is select * from service where car_id = null; 
touched_row service%ROWTYPE; 
BEGIN 
OPEN touched_rows; 
    LOOP 
    FETCH touched_rows INTO touched_row; 
    EXIT WHEN touched_rows%NOTFOUND; 
    UPDATE service SET car_id = choose_ideal_car(touched_row.period,touched_row.day) WHERE service_id = touched_row.service_id; 
    END LOOP; 
CLOSE touched_rows; 
end; 
/

出於某種原因,我的觸發從來沒有發射。

我也嘗試創建這樣的觸發器:

CREATE OR REPLACE TRIGGER service_set_car_id AFTER DELETE FROM cars FOR EACH ROW 
CURSOR touched_rows is select * from service where car_id = :old.car_id; 
... 

這是解僱,但拋出「變異的錯誤」,因爲功能choose_ideal_car使用從兩個表中選擇。也許這個解決方案是創建我的cars表的副本,並從我的choose_ideal_car函數中選擇它,而不是從cars表中選擇哪個是我定義的觸發器,但這對我來說聽起來不太合適。

雖然我寫這篇文章,我意識到,即使我的第一個觸發器被解僱,它將無法正常工作,並拋出相同的'變異錯誤'。

所以在最後我有兩個問題:

1)爲什麼第一個觸發從來沒有發射?

2)如何解決這個變異錯誤並使所有工作正常?

回答

0

where car_id = null返回行,使用where car_id is null代替

+0

BTW。當你沒有做任何額外的動作,除了循環中的更新,你可以只用一行代替遊標和循環:'UPDATE service SET car_id = choose_ideal_car(period,day)WHERE car_id IS NULL; ' –

+0

哦..那個空比較真的是愚蠢的錯誤... 如果我使用這個單行更新是不是有可能該函數計算一次,所有更新的行將具有相同的值? 我選擇循環是因爲函數的結果取決於「服務」表中的值,所以我想確保將爲每一行計算函數。 –

+0

@JanTomášek函數將計算每個受影響的行 –