对于某项任务,我的任务是创建一个非常简单的Q / A网站,其中包含标记的问题和评论的答案。
其中一个要求是使用触发器来检测重复标记的插入,如果是这种情况,则递增已存在的标记的使用计数器。
问题是,我无法通过回滚整个事务取消触发器,包括UPDATE
,这会触发触发器的目的。
关于如何实现这一目标的任何想法?
要求的措辞如下:
“创建触发器,检查数据库中以前是否存在任何要添加的标记。如果存在,相应行中的use列必须增加1 ”<登记/>
(原文:“ 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 “)
这个要求不能改变或避免,尽管欢迎漏洞。
作为参考,我当前的触发码:
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;
答案 0 :(得分:1)
这不是桌子上触发器的用途。
您应该使用存储过程中的MERGE
语句,INSTEAD OF
触发器或仅来自客户端:
MERGE
INTO tag tc
USING (
SELECT :NEW.nombre
FROM dual
) t
ON (tc.nombre = t.nombre)
WHEN MATCHED THEN
UPDATE
SET usos = usos + 1
WHEN NOT MATCHED THEN
INSERT (nombre, usos)
VALUES (nombre, 1)
在性能方面,最好从客户端传递集合中的所有标记并执行此查询:
MERGE
INTO tag tc
USING (
SELECT tag, COUNT(*) AS cnt
FROM TABLE(:mycollection)
GROUP BY
nombre
) t
ON (tc.nombre = t.nombre)
WHEN MATCHED THEN
UPDATE
SET usos = usos + cnt
WHEN NOT MATCHED THEN
INSERT (nombre, usos)
VALUES (nombre, cnt)
在存储过程中,它将接收集合作为参数。
答案 1 :(得分:0)
...或
将这种逻辑放在具有相同或相似结构的另一个表上。
然后当插入通过时,您使用后触发逻辑也将其插入主表。