在没有回滚的情况下取消插入内部的插入

时间:2010-09-12 23:11:05

标签: sql triggers oracle-xe

对于某项任务,我的任务是创建一个非常简单的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;

2 个答案:

答案 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)

...或

将这种逻辑放在具有相同或相似结构的另一个表上。

然后当插入通过时,您使用后触发逻辑也将其插入主表。