我有一个带有"tipo_quarto"的表"paciente",我需要一个触发器,每次我在"tipo_quarto"中插入一些东西时,表"quarto"都会更新"tipo"。
这是功能/触发器
CREATE OR REPLACE FUNCTION ADD_PACIENTE_QUARTO
(CONT IN VARCHAR Default Null)
RETURN VARCHAR
IS
PAC VARCHAR;
BEGIN
Select TIPO_QUARTO into PAC from PACIENTE
Where PAC = CONT;
return PAC;
END ADD_PACIENTE_QUARTO;
create or replace TRIGGER PACIENTE_TRIGGER
AFTER
INSERT OR UPDATE
ON TIPO_QUARTO
FOR EACH ROW
Declare
PAC VARCHAR;
BEGIN
PAC:=ADD_PACIENTE_QUARTO(:new.TIPO_QUARTO);
If :new.TIPO_QUARTO = 'UTI' then
PAC := PAC - :new.TIPO;
else
PAC := PAC + :new.TIPO;
End If;
UPDATE TIPO_QUARTO SET TIPO = PAC
WHERE TIPO = :new.TIPO;
END;
这是表格的;
太平洋
CREATE TABLE PACIENTE
(
PRIMEIRO_NOME VARCHAR(100) NOT NULL,
SEGUNDO_NOME VARCHAR(100) NOT NULL,
CPF NUMBER(11) NOT NULL,
IDADE NUMBER(3)NOT NULL,
SEXO VARCHAR(1)NOT NULL,
TIPO_QUARTO VARCHAR(3) NOT NULL,
CONSTRAINT PACIENTE_PK PRIMARY KEY(CPF)
);
TIPO_QUARTO
CREATE TABLE TIPO_QUARTO
(TIPO VARCHAR(3)NOT NULL,
PACIENTE_CPF NUMBER(11)NOT NULL,
CONSTRAINT TIPO_QUARTO PRIMARY KEY (TIPO),
CONSTRAINT TIPO_QUARTO_FK FOREIGN KEY(PACIENTE_CPF) REFERENCES PACIENTE(CPF)
);
看到你的表格,有些事情仍然不清楚。 你的函数ADD_PACIENTE_QUARTO
实现了一个SELECT
语句,该语句声明谓词Where PAC = CONT
但PAC
不在PACIENTE
的规范中,而是存储结果的局部变量,CONT
是你的参数,不清楚你在那里尝试了什么。
现在,触发器在逻辑和实现方面存在一些缺陷。
首先,你的触发器的名称是PACIENTE_TRIGGER
但INSERT OR UPDATE ON TIPO_QUARTO
行告诉我它在TIPO_QUARTO
表上,这在语法上不是问题,但从逻辑上讲,对于那些试图弄清楚触发器属于哪个表的人来说,这可能是一个痛苦的屁股。
接下来,使用 INSERT OR UPDATE OF TIPO ON TIPO_QUARTO
监视插入或仅更新表的列TIPO
中的更改TIPO_QUARTO
。
现在这一行If :new.TIPO_QUARTO = 'UTI' then
,假设这个触发器附加到TIPO_QUARTO
表,该表没有一个名为TIPO_QUARTO
将其更改为:new.TIPO
的列。
接下来,PAC
属于 VARCHAR
型,所以我不清楚你想在 PAC := PAC - :new.TIPO;
中做什么,PAC := PAC + :new.TIPO;
两行都会抛出invalid number
异常,因为你不能加减字符串,也许你的意图是连接或获取一个子字符串。
最后,在 TIPO_QUARTO
触发器内调用 UPDATE TIPO_QUARTO SET TIPO = PAC
将导致mutating table
异常,您无法查询/更新位于 DML 语句中间的表(在本例中为 INSERT 或 UPDATE(来解决此问题,您只需分配:new.TIPO := PAC
即可。
照顾好这些细节,也许那时你的问题就不会再存在了。