2013-02-09 66 views
1

我使用SQL和Oracle数据库,需要一些帮助 - 触发器是一些我很难理解。PL/SQL触发更新来自插入另一台在一个表上

我需要一个触发器,当我向表A中插入一行时,它会更新表B上的一行:特别是主键匹配刚添加到表A的行的相应外键的行。

因此,对于在表A实例列X是外键,它引用在表B柱Y(主密钥)。当我添加一行到表AI时,需要表B的列Z在列X =列Y的行中添加1到它的数值。

这是我在SQL中基于SQL在我有限的触发器的理解,在情况下,它可以帮助(我意识到这不是很好,把它当作伪代码):

CREATE OR REPLACE TRIGGER test_trig 
AFTER INSERT OR UPDATE ON tableA 
FOR EACH ROW 

BEGIN 
    UPDATE tableB 
    SET columnZ = columnZ + 1 
    WHERE tableA.columnX = tableB.columnY; 
END test_trig; 
/

感谢

回答

0

足够好的开始。

第一 - 让我们这样的出路 - 这是没有得到很好的标准化 - 你所描述的价值似乎像它应该在运行时不能在数据操作时间计算。

考虑以下几点:

插入= +1列 - 行

更新=?并不总是+1我想 - 可能只有当某些其他数据被修改时。例如 - 如果我更新表集合col1 = col1会怎么样。也许你想要的可能不是。

删除=?删除平均-1到列?

语法:

WHERE tableA.columnX = tableB.columnY; 

应该

WHERE :new.columnX = tableB.columnY; 
1

试试这个:

语法将

CREATE OR REPLACE TRIGGER test_trig 
AFTER INSERT OR UPDATE ON tableA 
FOR EACH ROW 

BEGIN 
    UPDATE tableB 
    SET columnZ = columnZ + 1 
    WHERE tableB.columnX = :NEW.columnX; 
END test_trig; 
/

:new.columnX引用表格中的columnX。

0

如果tableB.columnZ代表的参考表A记录的计数,没有意义触发TableA上的UPDATE除非表A的参考列可以改变。

首先OCASION:tableA.ReferenceColumn不会改变:

CREATE OR REPLACE TRIGGER test_trig 
AFTER INSERT ON tableA 
FOR EACH ROW 
BEGIN 

    UPDATE tableB 
    SET columnZ = columnZ + 1 
    WHERE tableB.columnX = :NEW.columnX; 
END test_trig; 
/

二OCASION:tableA.ReferenceColumn确实发生了改变:

CREATE OR REPLACE TRIGGER test_trig 
AFTER INSERT OR UPDATE OF columnX ON tableA 
FOR EACH ROW 

BEGIN 

    IF UPDATING AND nvl(:OLD.columnX,0) <> 0 THEN 
     UPDATE tableB 
     SET columnZ = columnZ - 1 
     WHERE tableB.columnX = :OLD.columnX; 
    END IF: 

    IF nvl(:NEW.columnX,0) <> 0 THEN 
     UPDATE tableB 
     SET columnZ = columnZ + 1 
     WHERE tableB.columnX = :NEW.columnX; 
    END IF; 

END test_trig; 
/

三OCASION:tablaA记录可以删除:

CREATE OR REPLACE TRIGGER test_trig 
AFTER INSERT OR DELETE OR UPDATE OF columnX ON tableA 
FOR EACH ROW 

BEGIN 
    IF (UPDATING OR DELETING) AND nvl(:OLD.columnX,0) <> 0 THEN 
     UPDATE tableB 
     SET columnZ = columnZ - 1 
     WHERE tableB.columnX = :OLD.columnX; 
    END IF: 

    IF nvl(:NEW.columnX,0) <> 0 THEN 
     UPDATE tableB 
     SET columnZ = columnZ + 1 
     WHERE tableB.columnX = :NEW.columnX; 
    END IF; 
END test_trig; 
/
0

我猜你正在实施一些机制(A)保持的历史(B)计数器或(C)数据完整性问题。 如果是这种情况,我会建议使用pl/sql包进行更新,该包将处理所有必要的更新/其他DML操作。 这是应用程序通过pl/sql包更新数据的最佳实践。通过这种方式,您可以在内部控制流程,并且更容易维护。另外,当你忘记在该表上有触发器时,你可以在将来保存自己的问题。

一个技巧,我可以为您提供有关触发器 - 在您决定使用触发器之前,请确保您已经耗尽其他所有可能性

相关问题