【发布时间】:2021-09-03 16:41:15
【问题描述】:
我想更新年龄小于 20 的表中的数据。所以我想更新 dob 并将其设置为年龄大于 20 的日期(通过使用更新后触发器)。我知道我说的没有任何意义,但这是我的教授给的任务。
我正在使用 Oracle Live SQL。
create table SYCS_DBMS(
SID NUMBER(10),
SNAME VARCHAR(50),
DOB DATE,
PRESENT DATE
);
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY';
INSERT INTO SYCS_DBMS VALUES(1, 'ANKIT', '4-OCTOBER-2002', sysdate);
INSERT INTO SYCS_DBMS VALUES(2, 'AAKASH', '30-OCTOBER-2002', sysdate);
INSERT INTO SYCS_DBMS VALUES(3, 'DHRUV', '5-APRIL-2002', sysdate);
INSERT INTO SYCS_DBMS VALUES(4, 'DEERAJ', '5-AUGUST-2002', sysdate);
INSERT INTO SYCS_DBMS VALUES(5, 'ADIL', '11-MARCH-2003', sysdate);
INSERT INTO SYCS_DBMS VALUES(6, 'VIRAJ', '7-JULY-2002', sysdate);
CREATE OR REPLACE TRIGGER trUPDT
AFTER UPDATE
ON SYCS_DBMS
FOR EACH ROW
DECLARE
STU_AGE NUMBER;
BEGIN
--TO CHECK THE AGE BY DATE OF BIRTH
SELECT MONTHS_BETWEEN(TO_DATE(sysdate,'DD-MON-YYYY'), TO_DATE(:NEW.DOB,'DD-MON-YYYY'))/12
INTO STU_AGE FROM DUAL;
END;
【问题讨论】:
-
计算20年前的日期。然后将
DOB设置为LEAST(:NEW.DOB, DATE_20_YR_AGO) -
"...update表中age小于20"和"...update dob 并将其设置为 age 大于 20" 的日期听起来很矛盾。请描述输入数据是什么,应该执行什么操作以及您期望的结果数据是什么。
-
您的日期格式已关闭:如果模板为
DD-MON-YYYY,则该值应包含 2 位数的日期和 3 字符的月份,例如04-OCT-2002。另外,我会将其作为 BEFORE INSERT 触发器来执行(您的示例实际上并没有进行任何更新!):修改DOB值作为原始 SQL 插入的一部分,而不是执行多个额外步骤在已应用后更改原始值。结果应该更快/更具可扩展性。 -
sysdate和dob是date类型,所以to_date函数在这里是多余的。您不需要将日期转换为日期。 -
@astentx - 将 to_date 应用于 DATE 比只是多余的更糟糕。它强制一个隐含的 TO_CHAR,这又依赖于 NLS_DATE_FORMAT 的控制设置。如果星星没有完美排列,就会导致错误,而不仅仅是额外的、不需要的工作。