PL/SQL:根据条件更新另一个表时未找到数据

Posted

技术标签:

【中文标题】PL/SQL:根据条件更新另一个表时未找到数据【英文标题】:PL/SQL: NO DATA FOUND while updating another table based on conditions 【发布时间】:2017-11-23 20:59:56 【问题描述】:

所以我的 PAYMENT 表上有一个名为 Status 的列。它具有另一个名为 reservation 的表的外键,带有 Reservation_ID。预订表也有一个状态列,只有在付款表的状态列中有值时才会更新。因此,如果付款表中的状态字段的值为“已确认”,则该特定 Reservation_ID 的值应该变为 1.. 否则为 22。这就是我制作触发器的方式:

CREATE OR REPLACE TRIGGER stats BEFORE INSERT OR DELETE OR UPDATE ON PAYMENT FOR EACH ROW
DECLARE
V_STATUS VARCHAR2(20);
BEGIN
SELECT Status INTO V_STATUS FROM PAYMENT INNER JOIN RESERVATION ON PAYMENT.Reservation_ID=RESERVATION.Reservation_ID WHERE PAYMENT.Reservation_ID=:NEW.Reservation_ID; 
IF INSERTING AND V_STATUS='CONFIRMED' THEN
UPDATE RESERVATION SET status=1 WHERE Reservation_ID=:new.Reservation_ID;
ELSIF UPDATING AND V_STATUS='CONFIRMED'  THEN
UPDATE RESERVATION SET status=1 WHERE Reservation_ID=:new.Reservation_ID;
ELSE
UPDATE RESERVATION SET status=22 WHERE Reservation_ID=:new.Reservation_ID;
END IF;
END;

所以触发器基本上被编译但是当我尝试在支付表中插入值时,我收到以下错误:

Error report -
ORA-01403: no data found
ORA-06512: at "ME.STATS", line 4
ORA-04088: error during execution of trigger 'ME.STATS'

为两个表创建语句:

CREATE TABLE RESERVATION(RESERVATION_id NUMBER(10) NOT NULL, MEMBER_ID NUMBER(10) CONSTRAINT RE_MEM_fk REFERENCES MEMBER(MEMBER_ID) ON DELETE SET NULL,status NUMBER(10) CONSTRAINT RES_status_fk REFERENCES STATUS(RESERVATION_status_id) ON DELETE SET NULL, CONSTRAINT PK_BOOK PRIMARY KEY(RESERVATION_id)); 
CREATE TABLE PAYMENT(Payment_ID NUMBER(10) NOT NULL ,RESERVATION_id NUMBER(10) CONSTRAINT Pay_RES_fk REFERENCES RESERVATION(RESERVATION_id) ON DELETE SET NULL, TicketPrice NUMBER(10), ExtraFaciliFees Number(10),TOTAL_AMOUNT Number(10), PromotionalCode VARCHAR2(10), CONSTRAINT PK_PAY PRIMARY KEY(Payment_ID));

【问题讨论】:

ELSIF 顺便说一句,请提供创建表以重现您的案例(minimal reproducible example) @Blag 预留表:CREATE TABLE RESERVATION(RESERVATION_id NUMBER(10) NOT NULL, MEMBER_ID NUMBER(10) CONSTRAINT RE_MEM_fk REFERENCES MEMBER(MEMBER_ID) ON DELETE SET NULL,status NUMBER(10) CONSTRAINT RES_status_fk REFERENCES STATUS(RESERVATION_status_id) ON DELETE SET NULL, CONSTRAINT PK_BOOK PRIMARY KEY(RESERVATION_id)); edit您的问题以添加更多信息;) 对于付款,CREATE TABLE PAYMENT(Payment_ID NUMBER(10) NOT NULL ,RESERVATION_id NUMBER(10) CONSTRAINT Pay_RES_fk REFERENCES RESERVATION(RESERVATION_id) ON DELETE SET NULL, TicketPrice NUMBER(10), ExtraFaciliFees Number(10) ),TOTAL_AMOUNT Number(10), PromotionalCode VARCHAR2(10), CONSTRAINT PK_PAY PRIMARY KEY(Payment_ID)); 【参考方案1】:

第一:

CREATE TABLE RESERVATION(
    Status NUMBER(10));

SELECT Status INTO V_STATUS

IF INSERTING AND V_STATUS='CONFIRMED'

您能解释一下您希望数字如何匹配字符串吗?


下一个(来自http://www.dba-oracle.com/sf_ora_01403_no_data_found.htm)

SELECT INTO 子句是标准的 SQL 查询,用于拉取一行或一组 数据库中的列,并将检索到的数据放入变量中 这是预定义的。

如果 SELECT INTO 语句至少没有返回 e 行, ORA-01403 被抛出。

所以这个:

SELECT
    Status INTO V_STATUS
FROM PAYMENT p
INNER JOIN RESERVATION r
    ON p.Reservation_ID = r.Reservation_ID
WHERE p.Reservation_ID = :NEW.Reservation_ID;

很可能根本不输出任何行...

【讨论】:

我在两个不同的表中使用了状态..预订和付款..付款中的应该是字符串..所以v_status应该取表付款的状态,然后如果v_status,哪个属于支付表,值为“已确认”,预订表中的状态字段将更新为数值 1.. 否则为 22【参考方案2】:

同意@Blag,下面的声明是给no data found exception。 一般来说,如果您想知道错误指向的确切行号,可以通过DBA_SOURCEALL_SOURCES 引用该对象。

SELECT
    Status INTO V_STATUS
FROM PAYMENT p
INNER JOIN RESERVATION r
    ON p.Reservation_ID = r.Reservation_ID
WHERE p.Reservation_ID = :NEW.Reservation_ID;

【讨论】:

以上是关于PL/SQL:根据条件更新另一个表时未找到数据的主要内容,如果未能解决你的问题,请参考以下文章

带有 where 条件的 PL/SQL 更新查询作为带有一些空值的选择查询

更新另一列时,使用列名作为 PL/SQL 关联数组的键

调用 Restful Web 服务和更新数据库表的 PL/SQL 过程

PL/SQL 中的验证检查

PL/SQL 和 Oracle Forms Builder

根据 PL/SQL 中的特定条件替换 IP-address 中的最后一个字符串