取消触发器内的插入而不回滚
对于某项作业,我的任务是创建一个非常简单的问答网站,其中包含标记的问题和评论的答案。
要求之一是要有一个触发器来检测重复标签的插入,如果是这种情况,则增加已存在标签的使用计数器。
问题是,我无法通过回滚整个事务(包括 UPDATE)来取消触发器,这违背了触发器的目的。
关于如何实现它有什么想法吗?
更新
要求的措辞如下:
“创建触发器来检查数据库中是否先前不存在要添加的任何标签。如果存在,则相应行中的 use 列必须增加 1”
(原文:“创建触发器 tg_insertar_tag
que revise que cualquier nuevo tag que se agregue no exita antes en la base de datos; >en caso de excistir, se debe Incrementar en 1 la columna “usos” de la tabla tag del registro que countera")
此要求无法更改或避免,但欢迎出现漏洞。
作为参考,我当前的触发代码:
CREATE OR REPLACE TRIGGER tg_insertar_tag BEFORE INSERT ON Tag
FOR EACH ROW
DECLARE
tagCount integer;
v_usos integer;
BEGIN
SELECT COUNT(*) INTO tagCount FROM Tag WHERE nombre = :new.nombre;
SELECT Usos INTO v_usos FROM Tag WHERE nombre = :new.nombre;
IF tagCount > 0 THEN
UPDATE Tag SET usos = v_usos + 1 WHERE nombre = :new.nombre;
ELSE
:new.usos := 1;
END IF;
END;
For a certain assignment, I'm tasked with creating a very simple Q/A site, complete with tagged questions and commented answers.
One of the requirements is to have a trigger to detect the insertion of duplicate tags and, if such is the case, increment the already-existing tag's usage counter.
Problem is, I can't cancel the trigger with rolling back the entire transaction, including the UPDATE
, which defeats the purpose of the trigger.
Any ideas on how to pull it off?
UPDATE
The requirement's phrased like follows:
"Create the trigger that checks if any tag to be added doesn't previously exist in the database. In case it exists, the use column in the corresponding row must be incremented by 1"
(Original language: "Crear el trigger tg_insertar_tag
que revise que cualquier nuevo tag que se agregue no exista antes en la base de datos; en caso de existir, se debe incrementar en 1 la columna “usos” de la tabla tag del registro que corresponda")
This requirement can't be changed or avoided, although loopholes would be welcome.
For reference, my current trigger code:
CREATE OR REPLACE TRIGGER tg_insertar_tag BEFORE INSERT ON Tag
FOR EACH ROW
DECLARE
tagCount integer;
v_usos integer;
BEGIN
SELECT COUNT(*) INTO tagCount FROM Tag WHERE nombre = :new.nombre;
SELECT Usos INTO v_usos FROM Tag WHERE nombre = :new.nombre;
IF tagCount > 0 THEN
UPDATE Tag SET usos = v_usos + 1 WHERE nombre = :new.nombre;
ELSE
:new.usos := 1;
END IF;
END;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这不是表上触发器的用途。
您应该使用来自存储过程、
INSTEAD OF
触发器或仅来自客户端的 MERGE 语句:从性能角度来看,最好传递集合中的所有标记从客户端执行此查询:
在存储过程中,该过程将接受集合作为参数。
That's not what the triggers on a table are for.
You should use a
MERGE
statement from a stored procedure, anINSTEAD OF
trigger or just from the client:Performance-wise, it would be best to pass all tags in a collection from the client and perform this query:
in the stored procedure which would accept the collection as a parameter.
或者...
将这种逻辑放在另一个具有相同或相似结构的表上。
然后,当插入通过时,您可以使用后触发逻辑将其插入主表中。
or...
place this kind of logic on another table with the same or similar structure.
then when the insert passes, you use a post trigger logic to also insert it into the primary table.