需要你的幫助交叉表數據驗證
我有2個連接的實體:庫讀者(訂戶)和書的問題。讀者可以在因爲破壞圖書館的規定天被鎖定一段時間:
我需要補充檢查,以便讀者,誰的鎖定期尚未結束,不能拿一本書在庫(換句話說,Issue.Taken> Subscriber.Lock_Date + Subscriber.Lock_Period)
請幫忙,我該怎麼做?
需要你的幫助交叉表數據驗證
我有2個連接的實體:庫讀者(訂戶)和書的問題。讀者可以在因爲破壞圖書館的規定天被鎖定一段時間:
我需要補充檢查,以便讀者,誰的鎖定期尚未結束,不能拿一本書在庫(換句話說,Issue.Taken> Subscriber.Lock_Date + Subscriber.Lock_Period)
請幫忙,我該怎麼做?
我MTO同意,這樣的驗證應該由應用程序代碼來處理(通過存儲過程)。但是,如果您堅持通過數據庫執行此驗證,那麼以下觸發器將會有所幫助。同樣,我不推薦這種解決方案,最好的方法是使用應用程序邏輯處理它。
CREATE OR REPLACE TRIGGER trg_val_lock_dt
BEFORE INSERT ON issue
FOR EACH ROW
DECLARE
v_is_valid CHAR(1);
BEGIN
v_is_valid := 'Y';
SELECT 'N' INTO v_is_valid
FROM subscriber s
WHERE :NEW.subscr_id = s.subscr_id
AND :NEW.taken BETWEEN s.lock_date AND (s.lock_date + lock_period);
RAISE_APPLICATION_ERROR(-20001,'The subscriber is locked');
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END;
上述觸發將在問題表中的每個插入之前進行發射。它將檢查所採用的日期是否在鎖定日期和鎖定日期+鎖定週期之間(這將是鎖定結束日期)。如果找到這樣的記錄,那麼它將拋出以下錯誤,並且該行不會被插入。
ORA-20001: The subscriber is locked
ORA-06512: at "RETAIL_1.TRG_VAL_LOCK_DT", line 12
如果條件不滿足,則沒有內容,將引發異常,其中觸發器將什麼也不做,行將被插入。
這應該在業務邏輯中真正處理,而不是在表級別處理。
但是,你可以使用物化視圖做到這一點:
CREATE TABLE subscriber (
id INT PRIMARY KEY,
lock_date DATE,
lock_period INTERVAL DAY(5) TO SECOND
);
CREATE TABLE issue (
id INT PRIMARY KEY,
subscr_id INT NOT NULL REFERENCES subscriber(id),
book_id INT,
taken DATE,
returned DATE
);
CREATE MATERIALIZED VIEW LOG ON subscriber
WITH SEQUENCE, ROWID(id, lock_date, lock_period)
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW LOG ON issue
WITH SEQUENCE, ROWID(subscr_id, taken)
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW subscriber_issue_MV
BUILD IMMEDIATE
REFRESH FAST ON COMMIT
AS SELECT s.id,
s.lock_date,
s.lock_period,
i.taken
FROM subscriber s
INNER JOIN
issue i
ON (i.subscr_id = s.id);
ALTER TABLE subscriber_issue_MV ADD CONSTRAINT subscriber_issue__mv__chk
CHECK ( lock_date IS NULL
OR lock_period IS NULL
OR NOT taken BETWEEN lock_date AND lock_date + lock_period);
它適用於在表中插入新行,但是當我嘗試返回書籍(或任何其他更新)時,我得到ORA-04091表是變異錯誤。我能繞過這個錯誤還是觸發限制? – JGDger
但觸發器只能在插入時觸發。它在更新上發射嗎? –
是的,錯誤引發更新,我不明白爲什麼 – JGDger