Database PL/SQL触发器从一个表上的INSERT更新另一个表
我正在使用SQL和Oracle数据库,需要一些帮助-触发器是我很难理解的东西 我需要一个触发器,用于在表a中插入一行以更新表B中的一行:特别是主键与刚刚添加到表a中的行的对应外键匹配的行 例如,表A中的列X是一个外键,它引用表B中的列Y(主键)。当我将一行添加到表a中时,我需要将表B的Z列添加到其数值中,其中X列=Y列 基于我对触发器的有限理解,这就是我迄今为止在SQL中所能得到的,以防它有所帮助(我意识到它不是很好,将其视为伪代码): 谢谢好的开始 首先,让我们把它放在一边-这不是很好的标准化-您描述的值似乎应该在运行时计算,而不是在数据操作时 考虑以下几点: 在列中插入=+1-确定 更新=?我想,并非总是对列加1-可能只有在修改某些其他数据时才加1。例如,如果我更新表a集合col1=col1会怎么样。也许是你想要的,也许不是 删除=?删除是指列中的-1吗 对于语法:Database PL/SQL触发器从一个表上的INSERT更新另一个表,database,oracle,plsql,Database,Oracle,Plsql,我正在使用SQL和Oracle数据库,需要一些帮助-触发器是我很难理解的东西 我需要一个触发器,用于在表a中插入一行以更新表B中的一行:特别是主键与刚刚添加到表a中的行的对应外键匹配的行 例如,表A中的列X是一个外键,它引用表B中的列Y(主键)。当我将一行添加到表a中时,我需要将表B的Z列添加到其数值中,其中X列=Y列 基于我对触发器的有限理解,这就是我迄今为止在SQL中所能得到的,以防它有所帮助(我意识到它不是很好,将其视为伪代码): 谢谢好的开始 首先,让我们把它放在一边-这不是很好的标准化
WHERE tableA.columnX = tableB.columnY;
应该是
WHERE :new.columnX = tableB.columnY;
试试这个:
语法将是
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引用表A columnX。如果tableB.columnZ表示引用的tableA记录的计数,则在tableA更新时触发没有意义,除非tableA的引用列可以更改 第一个位置: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;
/
第二个位置: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;
/
创建或替换触发器测试触发器
插入或更新表A上的columnX后
每行
开始
如果正在更新和nvl(:OLD.columnX,0)0,则
更新表B
设置columnZ=columnZ-1
其中tableB.columnX=:OLD.columnX;
如果:
如果nvl(:NEW.columnX,0)0,则
更新表B
设置columnZ=columnZ+1
其中tableB.columnX=:NEW.columnX;
如果结束;
结束测试触发;
/
第三个位置:可以删除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;
/
创建或替换触发器测试触发器
插入、删除或更新表格A上的columnX后
每行
开始
如果(更新或删除)和nvl(:OLD.columnX,0)为0,则
更新表B
设置columnZ=columnZ-1
其中tableB.columnX=:OLD.columnX;
如果:
如果nvl(:NEW.columnX,0)0,则
更新表B
设置columnZ=columnZ+1
其中tableB.columnX=:NEW.columnX;
如果结束;
结束测试触发;
/
我猜您正在实现某种机制,用于(A)保存历史记录(B)计数器或(C)数据完整性问题。
如果是这种情况,我建议使用pl/sql包执行更新,该包将处理所有必要的更新/其他DML操作。
通过pl/sql包更新数据是应用程序的最佳实践。通过这种方式,您可以在内部控制流程,并且更易于维护。另外,当你忘了在那张桌子上有一个触发器时,你可以在将来保存你的自我问题
我可以为您提供一个关于触发器的提示-在您决定使用触发器之前,请确保您已经用尽了所有其他可能性
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;
/