我正在尝试创建一个触发器,只要添加新行,它就会将列日期更新一个月。
这就是我所拥有的,有人能告诉我我做错了什么吗?
CREATE OR REPLACE TRIGGER tg_nextupdate
BEFORE INSERT
ON Vehicle
FOR EACH ROW
BEGIN
IF :NEW.NextUpdate = SYSDATE
THEN
SET NextUpdate = ADD_MONTHS(SYSDATE,1);
END IF;
END;
答案 0 :(得分:1)
不需要IF-END IF
块,只要插入新行,它就会有sysdate。因此,只需直接将NextUpdate
更新为ADD_MONTHS(SYSDATE,1)
即可。不需要检查IF :NEW.NextUpdate = SYSDATE
。
CREATE OR REPLACE TRIGGER tg_nextupdate
BEFORE INSERT
ON Vehicle
FOR EACH ROW
BEGIN
:NEW.NextUpdate = ADD_MONTHS(SYSDATE,1);
END;
答案 1 :(得分:0)
当NextUpdate仅包含日期时,您可能会遇到代码问题,而不包括小时,分钟和秒。 试试这个:
CREATE OR REPLACE TRIGGER tg_nextupdate
BEFORE INSERT
ON Vehicle
FOR EACH ROW
BEGIN
IF :NEW.NextUpdate = trunc(SYSDATE)
THEN
SET NextUpdate = ADD_MONTHS(SYSDATE,1);
END IF;
END;
或者向我们提供有关您想要的内容以及代码内容的更多详细信息。
答案 2 :(得分:0)
这就是我所拥有的,有人可以告诉我我做错了什么吗?
假设NextUpdate
拥有默认值SYSDATE
,正如已经说过的那样,IF
可能是"没必要" ...
... 但是,就我而言,我认为真正的问题是SYSDATE
并不能保证在每次调用时都返回相同的值。如果您不相信我,请尝试http://sqlfiddle.com/#!4/1f810/2
因此,您的专栏可能会被SYSDATE
正确初始化,例如" 2014年10月26日18:50:10 + 0000"。但是,在您的触发器中,SYSDATE
可能会很快返回" 2014年10月26日18:50:11 + 0000"。我承认,这将是运气不好。也许这在您的应用程序中是可以接受的。但在更一般的情况下,这可能很容易成为难以追踪的错误。
根据您的需要,我建议改为这三个选项中的一个:
1)假设SYSDATE
是一个神奇的值"意思是"嘿触发器!为NextUpdate
":
CREATE OR REPLACE TRIGGER tg_nextupdate
BEFORE INSERT
ON Vehicle
FOR EACH ROW
BEGIN
IF :NEW.NextUpdate <= SYSDATE
THEN
:NEW.NextUpdate := SYSDATE + INTERVAL '1' MONTH;
END IF;
END;
因此,过去任何时候都会触发新NextUpdate
的计算。包括过去的1。
2)从触发器覆盖NextUpdate
- 始终:
CREATE TABLE Vehicle (value NUMBER(10),
NextUpdate DATE)
-- ^^^^^^^^^^^^^^^
-- No need for default here
-- as we override values
/
CREATE OR REPLACE TRIGGER tg_nextupdate
BEFORE INSERT
ON Vehicle
FOR EACH ROW
BEGIN
:NEW.NextUpdate := SYSDATE + INTERVAL '1' MONTH;
END;
/
INSERT INTO Vehicle(value) VALUES (1)
/
INSERT INTO Vehicle VALUES (2, TO_DATE('30/10/2014','DD/MM/YYYY'))
/
INSERT INTO Vehicle VALUES (3, TO_DATE('30/12/2014','DD/MM/YYYY'))
/
INSERT INTO Vehicle VALUES (4, NULL)
/
3)将NextUpdate
默认设置为SYSDATE + INTERVAL&#39; 1&#39; MONTH,允许用户在插入时更改它。 如果您需要,触发器可能会保留LEAST
值(+/- 1秒错误,如前言中所述):
CREATE TABLE Vehicle (value NUMBER(10),
NextUpdate DATE DEFAULT SYSDATE + INTERVAL '1' MONTH)
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-- set default to the "most probable" value
/
CREATE OR REPLACE TRIGGER tg_nextupdate
BEFORE INSERT
ON Vehicle
FOR EACH ROW
DECLARE
LimitNextUpdate DATE := SYSDATE + INTERVAL '1' MONTH;
BEGIN
:NEW.NextUpdate := LEAST(LimitNextUpdate,
NVL(:NEW.NextUpdate,LimitNextUpdate));
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-- required if the used set the value to NULL
END;
/
INSERT INTO Vehicle(value) VALUES (1)
/
INSERT INTO Vehicle VALUES (2, TO_DATE('30/10/2014','DD/MM/YYYY'))
/
INSERT INTO Vehicle VALUES (3, TO_DATE('30/12/2014','DD/MM/YYYY'))
/
INSERT INTO Vehicle VALUES (4, NULL)
/
您需要添加额外的逻辑(在触发器中或作为检查约束),以便在过去拒绝NextUpdate
。