甲骨文:触发器不工作
Oracle: Trigger not working
我有这个触发器:
CREATE OR REPLACE TRIGGER trig_update_process_info
AFTER INSERT ON rocessstep FOR EACH ROW
DECLARE
audit_time TIMESTAMP(6);
found_flag NUMBER DEFAULT 0;
BEGIN
SELECT MAX(lastupdatetime) INTO audit_time
FROM processinfo
WHERE instance = :new.instance;
EXCEPTION
WHEN no_data_found THEN
found_flag := NULL;
IF found_flag IS NULL
THEN
INSERT INTO processinfo
VALUES (:new.instance, :new.step, :new.status, :new.iteration, :new.audittime);
ELSE
IF :new.audittime > audit_time
THEN
UPDATE processinfo
SET step = :new.step, lastupdatetime = :new.audittime, status = :new.status, iteration = :new.iteration
WHERE instance = :new.instance;
END IF;
END IF;
END;
但它不起作用。你能告诉我这个触发器有什么问题吗?
这里是目标 table:
CREATE TABLE PROCESSINFO(
INSTANCE CHAR(36 BYTE) NOT NULL,
STEP VARCHAR2(128 BYTE) NOT NULL,
STATUS NUMBER(*,0) NOT NULL,
ITERATION NUMBER(*,0) NOT NULL,
LASTUPDATETIME TIMESTAMP(6) NOT NULL
);
谢谢
由于聚合,您的查询永远不会抛出 no_data_found
。相反,如果没有匹配数据,则 audit_time
将为空,因此您可以对其进行测试 - 根本不需要 found_flag
。正如所写的那样,整个 if/else 部分都在异常处理程序中,因此永远无法对其进行评估(如果没有抛出异常,您可能希望命中 else 部分,但您没有单独的 begin/end 围绕查询,所以你没有正确构建块)。
...
BEGIN
SELECT MAX(LASTUPDATETIME) INTO AUDIT_TIME FROM PROCESSINFO
WHERE INSTANCE = :NEW.INSTANCE;
IF AUDIT_TIME IS NULL
THEN
INSERT INTO PROCESSINFO (INSTANCE, STEP, STATUS, ITERATION, LASTUPDATETIME)
VALUES (:NEW.INSTANCE, :NEW.STEP, :NEW.STATUS, :NEW.ITERATION, :NEW.AUDITTIME);
ELIF :NEW.AUDITTIME > AUDIT_TIME THEN
UPDATE PROCESSINFO SET STEP = :NEW.STEP, LASTUPDATETIME = :NEW.AUDITTIME,
STATUS = :NEW.STATUS, ITERATION = :NEW.ITERATION
WHERE INSTANCE = :NEW.INSTANCE;
END IF;
END;
看起来每个 instance
在 processinfo
中只有一行,所以你也可以考虑合并语句而不是选择是更新还是插入。
ON ROCESSSTEP
看起来也很奇怪,但如果 table 名称错误,则根本不会创建触发器,而不仅仅是 'not working'.
我有这个触发器:
CREATE OR REPLACE TRIGGER trig_update_process_info
AFTER INSERT ON rocessstep FOR EACH ROW
DECLARE
audit_time TIMESTAMP(6);
found_flag NUMBER DEFAULT 0;
BEGIN
SELECT MAX(lastupdatetime) INTO audit_time
FROM processinfo
WHERE instance = :new.instance;
EXCEPTION
WHEN no_data_found THEN
found_flag := NULL;
IF found_flag IS NULL
THEN
INSERT INTO processinfo
VALUES (:new.instance, :new.step, :new.status, :new.iteration, :new.audittime);
ELSE
IF :new.audittime > audit_time
THEN
UPDATE processinfo
SET step = :new.step, lastupdatetime = :new.audittime, status = :new.status, iteration = :new.iteration
WHERE instance = :new.instance;
END IF;
END IF;
END;
但它不起作用。你能告诉我这个触发器有什么问题吗?
这里是目标 table:
CREATE TABLE PROCESSINFO( INSTANCE CHAR(36 BYTE) NOT NULL, STEP VARCHAR2(128 BYTE) NOT NULL, STATUS NUMBER(*,0) NOT NULL, ITERATION NUMBER(*,0) NOT NULL, LASTUPDATETIME TIMESTAMP(6) NOT NULL );
谢谢
由于聚合,您的查询永远不会抛出 no_data_found
。相反,如果没有匹配数据,则 audit_time
将为空,因此您可以对其进行测试 - 根本不需要 found_flag
。正如所写的那样,整个 if/else 部分都在异常处理程序中,因此永远无法对其进行评估(如果没有抛出异常,您可能希望命中 else 部分,但您没有单独的 begin/end 围绕查询,所以你没有正确构建块)。
...
BEGIN
SELECT MAX(LASTUPDATETIME) INTO AUDIT_TIME FROM PROCESSINFO
WHERE INSTANCE = :NEW.INSTANCE;
IF AUDIT_TIME IS NULL
THEN
INSERT INTO PROCESSINFO (INSTANCE, STEP, STATUS, ITERATION, LASTUPDATETIME)
VALUES (:NEW.INSTANCE, :NEW.STEP, :NEW.STATUS, :NEW.ITERATION, :NEW.AUDITTIME);
ELIF :NEW.AUDITTIME > AUDIT_TIME THEN
UPDATE PROCESSINFO SET STEP = :NEW.STEP, LASTUPDATETIME = :NEW.AUDITTIME,
STATUS = :NEW.STATUS, ITERATION = :NEW.ITERATION
WHERE INSTANCE = :NEW.INSTANCE;
END IF;
END;
看起来每个 instance
在 processinfo
中只有一行,所以你也可以考虑合并语句而不是选择是更新还是插入。
ON ROCESSSTEP
看起来也很奇怪,但如果 table 名称错误,则根本不会创建触发器,而不仅仅是 'not working'.