plsql - PL/SQL Ttrigger 从具有相同行的 2 个表中选择数据
问题描述
我有一个小项目的问题。我有这些表:
USER (TAG VARCHAR, NICKNAME VARCHAR, TAG_CLAN VARCHAR)
DONATION(DATE_DON DATE, DON_SEND VARCHAR, DON_REIC VARCHAR)
元素:DON_SEND 和 DON_REICV 是指向表用户的 MANI(标签)的外键。
我正在尝试创建一个触发器,仅当 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;
你能帮我吗?
解决方案
您发布的表格与触发器的代码之间存在一些差异。像这样的表:
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'
你的代码中的问题是你做了一个连接,假设你插入的记录已经存在于 table 中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')
推荐阅读
- html - flexbox 水平居中多个项目奇怪的图像
- reflection - lombok @NonNull on Field not readable using getAnnotations
- java - 构建spring-framework错误(无法解析插件工件'com.gradle.enterprise:com.gradle.enterprise.gradle.plugin:3.2')
- git - 从分支获取新的签入更改
- javascript - 如何在 DENO 中使用 npm 模块?
- security - 在路径而不是域根目录中托管数字资产链接 json 文件?
- azure-cosmosdb - DocumentDB 中复合索引的 ARM 模板
- prolog - 查找任何给定列表的最长可能回文
- docker - 在詹金斯管道中创建硒后端
- javascript - 无法关闭 JSX。解析错误:未终止的 JSX 内容