我有这张表描述某种图书馆的书籍贷款:
ImageListView
我想制作一个触发器,当您插入新贷款时,将贷款日期设置为今天,并将当天的返还日期设置为+ 21天。有代码,有效:
create table emprunt (
num_ab number(6,0) REFERENCES abonne(numero),
num_ex number (4,0) REFERENCES exemplaire(numero),
d_emprunt date,
d_retour date,
d_ret_reel date,
nb_relance number(1,0) CHECK (nb_relance IN (1,2,3)),
CONSTRAINT pk_emprunt PRIMARY KEY (num_ab, num_ex, d_emprunt)
);
但是问题是不再检查表格中的主要约束...例如,如果我多次:
CREATE OR REPLACE TRIGGER on_insert_emprunt
BEFORE INSERT ON emprunt
FOR EACH ROW
BEGIN
:NEW.d_emprunt := SYSDATE;
:NEW.d_retour := SYSDATE + 21;
END;
/
它完美无缺......而不是说我:
违反了UNIQUE CONSTRAINT
我在表格中有多个相同的行...
PS:抱歉用法语表。
答案 0 :(得分:1)
SYSDATE
具有时间组件。您重复插入的时间与触发器的时间不同,除非您碰巧在一秒钟内进行两次插入,否则您不会看到约束违规。日期不同(下至时间级别),因此用于主键的值不同 - 因此没有约束违规。
通过查询,您可以看到主键不同:
SELECT TO_CHAR(d_emprunt, 'YYYY-MM-DD HH24:MI:SS') AS d_emprunt,
TO_CHAR(d_retour, 'YYYY-MM-DD HH24:MI:SS') AS d_retour
FROM emprunt
WHERE num_ab = 921102
AND num_ex = 1010;
D_EMPRUNT D_RETOUR
------------------- -------------------
2015-04-29 10:55:30 2015-05-20 10:55:30
2015-04-29 10:55:35 2015-05-20 10:55:35
您会看到所插入的所有记录的时间不尽相同。
如果您想将日期设置为午夜you can truncate them,默认情况下会将时间组件重置为零:
CREATE OR REPLACE TRIGGER on_insert_emprunt
BEFORE INSERT ON emprunt
FOR EACH ROW
BEGIN
:NEW.d_emprunt := TRUNC(SYSDATE);
:NEW.d_retour := TRUNC(SYSDATE) + 21;
END;
/
顺便说一句,您的主键看起来效果不是很好。如果意图是阻止同一本书同时借出两次,那就不是那么做了。它阻止了这本书在同一天出借,但不是重叠期间。因此,如果我明天拿出同一本书,主键值仍然是唯一的,但范围会重叠。
答案 1 :(得分:0)
主键检查
(num_ab, num_ex, d_emprunt)
作为一个整体独特。
当您将数据num_ab and num_ex
插入相同但d_emprunt
为sysdate
时。
它正在改变。
如果您在1秒内插入两次数据,则会收到错误。