微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

处理 ORA-01403:触发器中没有发现异常的数据

如何解决处理 ORA-01403:触发器中没有发现异常的数据

我有两张桌子:

CREATE TABLE Patient
(
    p_Name  VARCHAR2(20) NOT NULL,p_Surname VARCHAR2(20) NOT NULL,idP     INTEGER,b_Date  DATE NOT NULL,d_Date  DATE DEFAULT NULL,CONSTRAINT PK_idP PRIMARY KEY(idP)
);

CREATE TABLE Visit 
(
    idV   INTEGER,date_V  DATE NOT NULL,v_Hospital INTEGER NOT NULL,id_PV   INTEGER,CONSTRAINT PK_idV PRIMARY KEY(idV),CONSTRAINT FK_idPV FOREIGN KEY(id_PV) REFERENCES Patient(idp)
        ON DELETE CASCADE,CONSTRAINT FK_idHV FOREIGN KEY(v_Hospital) REFERENCES Hospital(idH)
        ON DELETE CASCADE
);

我创建了一个触发器,这样当我在表 Visit 中插入一行时,如果患者已故(当然),它不应该允许我这样做,这就是它背后的逻辑。

CREATE OR REPLACE TRIGGER visitDeceased
BEFORE INSERT ON Visit
FOR EACH ROW
DECLARE
    pd Patient.d_date%TYPE;
BEGIN
    SELECT P.d_date INTO pd
    FROM Patient P JOIN Visit V ON P.idP=:NEW.id_PV;
EXCEPTION 
    WHEN NO_DATA_FOUND THEN  
        INSERT INTO Visit(date_V,v_Hospital,id_PV) VALUES(:NEW.date_V,:NEW.v_Hospital,:NEW.id_PV);
    WHEN OTHERS THEN
        RAISE_APPLICATION_ERROR(-20111,'Error. Patient deceased.'); 
END;
/

问题是当 d_date 为 NULL 时,代码生成 ORA-01403: no data found 错误。我正在尝试使用该异常处理它,但不起作用。有人知道如何使它工作吗?非常感谢。

解决方法

如果您希望一行匹配并且可以使用 NULL 值来处理不匹配,那么我发现聚合很方便:

SELECT MAX(P.d_date) INTO pd
FROM Patient P JOIN
     Visit V
     ON P.idP = :NEW.id_PV;

但是,在您的代码中,我只会使用 INSERT . . . SELECT

INSERT INTO Visit (date_V,v_Hospital,id_PV) V. 
    SELECT :NEW.date_V,:NEW.v_Hospital,:NEW.id_PV
    FROM dual
    WHERE NOT EXISTS (SELECT 1
                      FROM Patient p
                      WHERE p.idP = :NEW.id_PV
                     );

出于法律原因,您可能必须将已故患者从 Patient 中移除。但是,如果这不是必需的,我建议改用标志或 deceased_date

此外,可以通过使用外键约束来避免这个问题。这将验证关系完整性,而无需依赖触发器。

,

希望,我正确理解了您的问题。

NO_DATA_FOUNDSELECT P.d_date INTO pd FROM Patient P JOIN Visit V ON P.idP=:NEW.id_PV; 不返回任何行时处理异常。当此查询存在行时,它不会处理,但是,d_date 为空。根据您的表结构 d_Date DATE DEFAULT NULL,这是可能的。您可以通过以下方式处理:

*在 pd 查询后检查 select 是否为空。 例如:

IF pd IS NULL THEN    
-- do your work 
END IF;

OR

*在下面的查询中添加一个检查 where P.d_date is not null

SELECT P.d_date INTO pd FROM Patient P JOIN Visit V ON P.idP=:NEW.id_PV where P.d_date is not null;

,

当您在 VISIT 表上的 insert 语句上运行触发器时,为什么要在其中使用 Insert 语句?只需删除您的 Insert 语句,然后它就可以工作了 -

CREATE OR REPLACE TRIGGER visitDeceased
BEFORE INSERT ON Visit
FOR EACH ROW
DECLARE
    pd Patient.d_date%TYPE;
BEGIN
    SELECT P.d_date INTO pd
    FROM Patient P JOIN Visit V ON P.idP=:NEW.id_PV;
EXCEPTION
    WHEN OTHERS THEN
        RAISE_APPLICATION_ERROR(-20111,'Error. Patient deceased.'); 
END;
/

Link.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?