USER (TAG VARCHAR, NICKNAME VARCHAR, TAG_CLAN VARCHAR)
DONATION(DATE_DON DATE, DON_SEND VARCHAR, DON_REIC VARCHAR)
元素:DON_SEND和DON_REICV是表格用户的MANI(TAG)的外键。
我正在尝试制作一个触发器,只有在TAG_CLAN相同时才允许用户制作和接收捐赠
我试过这种方式,但它不起作用:
CREATE OR REPLACE TRIGGER CONTROLLO_USER_DONAZIONE
BEFORE INSERT ON DONAZIONE
FOR EACH ROW
DECLARE
TAG_C1 UTENTE.NUM_CLAN%TYPE;
TAG_C2 UTENTE.NUM_CLAN%TYPE;
CLAN_DIFF EXCEPTION;
BEGIN
SELECT U.NUM_CLAN INTO TAG_C1
FROM DONAZIONE D JOIN UTENTE U ON D.COD_UTENTE_EFFETTUA=U.TAG_USER
WHERE D.COD_UTENTE_EFFETTUA=(:NEW.COD_UTENTE_EFFETTUA);
SELECT U.NUM_CLAN INTO TAG_C2
FROM DONAZIONE D JOIN UTENTE U ON D.COD_UTENTE_RICEVE=U.TAG_USER
WHERE D.COD_UTENTE_RICEVE=(:NEW.COD_UTENTE_RICEVE);
IF TAG_C1<>TAG_C2 THEN
RAISE CLAN_DIFF;
END IF;
EXCEPTION
WHEN CLAN_DIFF THEN
RAISE_APPLICATION_ERROR(-20003,'NON SIETE NELLO STESSO CLAN, QUINDI NON PUOI RICEVERE/DONARE CARTE!');
END;
你能帮我吗?
答案 0 :(得分:0)
您发布的表格和触发器代码之间存在一些差异。使用这样的表:
CREATE TABLE utente
(
TAG_USER VARCHAR2(10) PRIMARY KEY,
NICKNAME VARCHAR2(10),
NUM_CLAN VARCHAR2(10)
);
CREATE TABLE DONAZIONE
(
DATE_DON DATE,
COD_UTENTE_EFFETTUA VARCHAR2(10) REFERENCES utente(TAG_USER),
COD_UTENTE_RICEVE VARCHAR2(10) REFERENCES utente(TAG_USER)
);
这可能是你的触发器:
CREATE OR REPLACE TRIGGER CONTROLLO_USER_DONAZIONE
BEFORE INSERT
ON DONAZIONE
FOR EACH ROW
DECLARE
TAG_C1 UTENTE.NUM_CLAN%TYPE;
TAG_C2 UTENTE.NUM_CLAN%TYPE;
CLAN_DIFF EXCEPTION;
BEGIN
SELECT U.NUM_CLAN
INTO TAG_C1
FROM UTENTE U
WHERE U.TAG_USER = :NEW.COD_UTENTE_EFFETTUA;
SELECT U.NUM_CLAN
INTO TAG_C2
FROM UTENTE U
WHERE U.TAG_USER = :NEW.COD_UTENTE_RICEVE;
IF TAG_C1 <> TAG_C2
THEN
RAISE CLAN_DIFF;
END IF;
EXCEPTION
WHEN CLAN_DIFF
THEN
RAISE_APPLICATION_ERROR(-20003, 'NON SIETE NELLO STESSO CLAN, QUINDI NON PUOI RICEVERE/DONARE CARTE!');
END;
使用以下数据:
insert into utente(TAG_USER, NICKNAME, NUM_CLAN) values ('one', 'User one', 'Numbers');
insert into utente(TAG_USER, NICKNAME, NUM_CLAN) values ('two', 'User two', 'Numbers');
insert into utente(TAG_USER, NICKNAME, NUM_CLAN) values ('a', 'User a', 'Letters');
它的工作原理如下:
SQL> insert into donazione(DATE_DON, COD_UTENTE_EFFETTUA, COD_UTENTE_RICEVE) values (sysdate, 'one', 'two');
1 row created.
SQL> insert into donazione(DATE_DON, COD_UTENTE_EFFETTUA, COD_UTENTE_RICEVE) values (sysdate, 'a', 'two');
insert into donazione(DATE_DON, COD_UTENTE_EFFETTUA, COD_UTENTE_RICEVE) values (sysdate, 'a', 'two')
*
ERROR at line 1:
ORA-20003: NON SIETE NELLO STESSO CLAN, QUINDI NON PUOI RICEVERE/DONARE CARTE!
ORA-06512: at "ALEK.CONTROLLO_USER_DONAZIONE", line 23
ORA-04088: error during execution of trigger 'ALEK.CONTROLLO_USER_DONAZIONE'
代码中的问题是你做了一个连接,假设你插入的记录已经存在于表DONAZIONE
中,这会得到一个no_data_found异常。
顺便说一句,我将varchar
更改为varchar2
;看看它们之间的区别。
此外,这假定NUM_CLAN
始终为NOT NULL
。
编辑:
鉴于您需要处理空值的方式,您可以编辑IF
IF TAG_C1 <> TAG_C2
到
IF TAG_C1 <> TAG_C2 or TAG_C1 is null or TAG_C2 is null
或者,更紧凑,但不太可读:
IF nvl(TAG_C1, 'a value that a clan can never have') <> nvl(TAG_C2 , 'some other impossible value')