触发器中的 ORACLE SQL 更新语句在 2 行后不起作用
Posted
技术标签:
【中文标题】触发器中的 ORACLE SQL 更新语句在 2 行后不起作用【英文标题】:ORACLE SQL UPDATE STATEMENT IN TRIGGER NOT WORKING AFTER 2 ROWS 【发布时间】:2021-04-30 06:51:03 【问题描述】:CREATE OR REPLACE TRIGGER BILL_TRG
BEFORE INSERT ON bill
FOR EACH ROW
DECLARE
d_id VARCHAR2(20);
doc_id VARCHAR2(20);
R_ID VARCHAR2(20);
p_name varchar2(20);
BEGIN
IF :NEW.BILL_NO IS NULL THEN
SELECT BILL_NO_SEQ.NEXTVAL INTO :NEW.BILL_NO FROM DUAL;
END IF;
IF :NEW.BILL_DATE IS NULL THEN
UPDATE BILL set BILL_DATE=TO_CHAR(SYSDATE);
END IF;
IF :NEW.p_name IS NULL THEN
SELECT p_name INTO :NEW.P_NAME FROM PATIENT WHERE P_ID=:NEW.P_ID;
END IF;
IF :NEW.P_GENDER IS NULL THEN
SELECT P_GENDER INTO :NEW.P_GENDER FROM PATIENT WHERE P_ID=:NEW.P_ID;
END IF;
IF :NEW.P_ADDRESS IS NULL THEN
SELECT P_ADDRESS INTO :NEW.P_ADDRESS FROM PATIENT WHERE P_ID=:NEW.P_ID;
END IF;
IF :NEW.D_NAME IS NULL THEN
SELECT D_ID INTO DOC_ID FROM PATIENT WHERE P_ID=:NEW.P_ID;
SELECT D_NAME INTO :NEW.D_NAME FROM DOCTOR WHERE D_ID = DOC_ID;
END IF;
IF :NEW.DATE_ADMISSION IS NULL THEN
SELECT DATE_ADMISSION INTO :NEW.DATE_ADMISSION FROM PATIENT WHERE P_ID=:NEW.P_ID;
END IF;
IF :NEW.days_admitted IS NULL THEN
UPDATE BILL SET DAYS_ADMITTED=abs(to_date(date_admission)-to_date(date_discharge));
END IF;
IF :NEW.room_charges IS NULL THEN
SELECT room_id INTO R_ID FROM PATIENT WHERE P_ID=:NEW.P_ID;
SELECT room_charges INTO :NEW.room_charges FROM room WHERE room_id=R_ID;
UPDATE BILL SET ROOM_CHARGES=ROOM_CHARGES*DAYS_ADMITTED;
END IF;
IF :NEW.total_amount IS NULL THEN
UPDATE BILL SET TOTAL_AMOUNT=ROOM_CHARGES+PATHOLOGY_FEES+D_FEES+MISCELLANEOUS;
END IF;
END;
/
首先,我使用的是 Oracle SQL Developer。 在此触发器中,我使用了三个更新语句....它们工作正常,直到两行,之后....值变为 null。
谁能帮我解决这个问题?
This update statement is working till 2 rows only.....after that it is not working.....I am attaching a screenshot of one of the columns.
Attaching 2nd picture here
【问题讨论】:
你能展示一些表格中的示例数据吗? 我已经上传了2张图片......请检查一下。 我只是想问......为什么在触发器中使用更新语句,第三条记录不可见。 请解释一下代码应该做什么。我没有投反对票。但是您可能会惊讶地发现,非工作代码通常不能很好地提供代码intent的上下文和解释。 【参考方案1】:为什么使用update
而不是直接赋值?您无法更新尚未插入的行,因此您输入的最后一行将始终不正确,并且您将无缘无故更新表中的所有其他行。
总体而言,您的代码和数据模型似乎存在一些重大问题:
-
您正在将日期存储为文本
当直接分配(例如
NEW.BILL_NO := NVL(:NEW.BILL_NO,BILL_NO_SEQ.NEXTVAL);
)可以工作时,您使用select into
您应该避免使用 SQL 连接
减少 SQL 执行次数(例如SELECT D_NAME INTO :NEW.D_NAME FROM DOCTOR D, PATIENT P WHERE D.D_ID = P.D_ID AND P.P_ID = :NEW.P_ID;
)
您正在使用update
修改同一个表的所有行
调用触发器除了实际插入的行
to_date 或 to_char 过滤器没有格式验证(如果您实际存储日期而不是文本,则不需要)
当您可以简单地反转时,您对 abs 使用了 不必要的函数调用
两个日期的顺序
【讨论】:
以上是关于触发器中的 ORACLE SQL 更新语句在 2 行后不起作用的主要内容,如果未能解决你的问题,请参考以下文章