oracle更新一行数据,另一个会话读取是为啥会产生2个CR块?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle更新一行数据,另一个会话读取是为啥会产生2个CR块?相关的知识,希望对你有一定的参考价值。

参考技术A 可能你的数据没提交,另一个会话读的是UNDO段内的东西,也就是你修改之前的数据追问

数据是没有提交,那应该只构造一个CR块

在触发器期间更新oracle中的同一行?

【中文标题】在触发器期间更新oracle中的同一行?【英文标题】:Updating the same row in oracle during a trigger? 【发布时间】:2012-02-27 15:08:48 【问题描述】:

简短的问题,因为我不知道如何搜索。我可以“重新更新”同一行吗?例如,我有一个存储付款小计的字段,并且鉴于我的业务限制,我可以更新该值。我可以只用触发器更新同一行的总数吗?提前谢谢你!

顺便说一下,我使用的是 Oracle 和 PL/SQL。

业务规则:我有以下。有一个存储将支付数据的表,另一个存储要支付的月费的表,以及另一个存储可能的折扣的表。 one will pay 只能打折一次,will pay 存储小计和总计。所以,我正在做的是......“在更新折扣信息时,在提交后,更新总价值和费用值”。

【问题讨论】:

【参考方案1】:

您无法更新触发器触发的表,您将收到 ORA-04091 mutating table 错误。您可以使用 :NEW 语法更新行本身中的值,只要它是“之前”触发器即可。

不过,我不清楚您对小计是什么意思;听起来您的桌子上有一个运行总计字段;如果那是基于同一张表上的其他记录(例如,您有多个相同订单的记录,并且您希望插入的记录具有所有先前记录的总和)。如果是这种情况,那么您也不能这样做,因为您会遇到相同的 ORA-04901。

如果您要更新一行,那么您可以调整一个字段,例如设置:NEW.subtotal := :OLD.subtotal - :OLD.value + :NEW.value,但不确定该字段有什么好处。

了解您的业务逻辑是什么以及它如何适应插入/更新以及您希望触发器做什么会很有帮助。通常对于这样的事情,您确实希望在插入/更新周围使用包装程序,而不是触发器,但目前它有点模糊。

为了使小计保持准确,我可能会避免尝试全部维护,而是使用具有分析函数为您计算它的视图。根据我的经验,麻烦要少得多。

【讨论】:

@user1231958 - 我肯定会看一个存储过程来做到这一点。可能在提交之前进行更新,以避免同时更新搞砸的风险。 如果由于某种原因有人进入 SQL*Plus 控制台或类似的东西,并以错误的方式插入/更新数据,导致一切都搞砸了怎么办? @user1231958 - 这听起来很圆滑,但如果它那么脆弱......不要让他们。任何人都不应该作为表的所有者进行连接,他们可以使用其他 ID 并具有由角色和授权控制的访问权限。然后,根本不要给任何人在表上插入/更新权限,让他们在过程(或更可能的过程包)上执行。如果由于某种原因无法做到这一点,那么计算数字的视图可能仍然有效。 这是不可能的,因为我的教授可能会仔细检查表格,因此他将拥有此访问权限。 @user1231958 - 我完全错过了作业标签。我不确定它如何强制执行仅限一次折扣的规则,但也许您只需要使用插入前触发器将subtotal 设置为total - discount。真的不确定您的教授在这里寻找什么,或者您所学的内容 - 我猜,解决方案应该与您应该知道的内容有些相似。【参考方案2】:

是的 - BEFORE INSERT for each row 触发器可以修改正在插入的值。

【讨论】:

那是在 INSERT 完成之后 - 一旦插入行,您就无法更改行,

以上是关于oracle更新一行数据,另一个会话读取是为啥会产生2个CR块?的主要内容,如果未能解决你的问题,请参考以下文章

oracle用户设置登录次数为unlimit,为啥用户还是被锁

高分求助:oracle 大表更新,大约200万,insert和update太慢,如何解决?

更新一行以基于另一行的转换 (Oracle)

Oracle:Sql根据同一表另一行的值更新同一表的行

为啥数据库经此会话中的活动事务已由另外一个会话提交或终止

平时使用oracle时,为啥会锁表