我正在为使用Oracle的项目开发某些功能。
我有两个表Inventory
和Transaction
,其中Inventory
表中有几行项目,每行都有一个ID
和Count
,例如:{{ 1}}
ID = 'ProductA' Count = 12
表具有多行事务,具有Transaction
,TXID
,ItemID
,例如:ItemQuantity
进行新交易时,我需要能够更新TXID = '00012', ItemID = 'ProductA', ItemQuantity = 5
中的物品计数。
我可以用多条语句来做到这一点,
Inventory
`
但是这似乎并不正确,如果出现一些错误而不是所有语句都执行该怎么办。
我应该为这种功能使用哪种格式?
答案 0 :(得分:2)
听起来非常像您想使用SQL "transactions"。
例如:
-- In Oracle, this begins an implicit transaction
INSERT INTO "TRANSACTION"(TRANSACTIONID ....) VALUES('00012 .....)
UPDATE INVENTORY SET Count = Count - ItemQuantity WHERE ROWID='ProductA'
COMMIT
要使其正常工作,您将需要“ ItemQuantity”作为某种变量。我想您是从PHP阅读的:您可以使用PHP变量开始。
更好的是,考虑使用Prepared Statements和/或Stored Procedures。
您还可以考虑将“ TRANSACTIONID”配置为Identity Column。
其他信息:
事务是一个逻辑的原子工作单元,包含一个或多个 更多SQL语句。
事务将SQL语句分组,以便它们全部 已提交,这意味着它们已应用到数据库或全部滚动 返回,这意味着它们已从数据库中撤消。甲骨文数据库 为每个交易分配一个唯一的标识符,称为交易ID。
所有Oracle事务都遵循数据库的基本属性 交易,称为ACID属性
事务从第一个可执行的SQL语句开始。一种 事务在提交或回退时结束 显式使用COMMIT或ROLLBACK语句,或隐式 发出DDL语句。
答案 1 :(得分:1)
您要在表Transaction
上寻找触发,以更新Inventory
表。
使用此解决方案,您无需执行2条语句(1条就足够了)。您还可以无缝地受益于原子事务,因为从概念上讲,触发器内进行的更改与触发它的操作属于同一事务。
工作方式:
在INSERT
Transaction
操作之后,Oracle都会触发触发器
在触发器内,您可以使用前缀Transaction
访问刚插入:NEW
的值;您使用这些值来更新Inventory
代码:
CREATE OR REPLACE TRIGGER update_inventory_after_transaction
AFTER INSERT ON transaction
FOR EACH ROW
BEGIN
UPDATE inventory SET Count = Count - :NEW.ItemQuantity WHERE ROWID = :NEW.ID;
END;
/
关于交易管理,根据the Oracle docs:
...如果触发器运行引发异常的语句,并且该异常未由异常处理程序处理,则数据库将回滚触发器及其触发语句的效果。
创建触发器后,每次在INSERT
上运行Transaction
操作时,都会发生此事:
COMMIT