Oracle DB,交易中的库存存量变化

时间:2018-12-13 21:10:35

标签: php sql oracle

我正在为使用Oracle的项目开发某些功能。 我有两个表InventoryTransaction,其中Inventory表中有几行项目,每行都有一个IDCount,例如:{{ 1}}

ID = 'ProductA' Count = 12表具有多行事务,具有TransactionTXIDItemID,例如:ItemQuantity

进行新交易时,我需要能够更新TXID = '00012', ItemID = 'ProductA', ItemQuantity = 5中的物品计数。

我可以用多条语句来做到这一点,

Inventory

`

但是这似乎并不正确,如果出现一些错误而不是所有语句都执行该怎么办。

我应该为这种功能使用哪种格式?

2 个答案:

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