如何避免触发器内的 ORA-04091 错误

2023-12-11

我在表 A 上有一个更新后触发器(触发器 A),可以对表 B 进行更改。

我在表 B 上还有一个更新后触发器(触发器 B),它不进行任何更改,但查询表 A 以对非规范化进行一些健全性检查。

因此触发器 B 可以通过以下两种方式之一触发:

  1. 如果我直接更新表 B,或者
  2. 如果我更新表 A 和触发器 A 触发,导致表 B 更新。

在情况 2 中,我收到 ORA-04091: table name is mutating, trigger/function may not see it 错误。这似乎是正确的。

我想在触发器 B 中检查表 A 是否“处于不良状态”并提前退出(在这种情况下不需要运行健全性检查)。

在我的触发器中测试此功能的最佳方法是什么?只需添加一个吞掉异常的异常处理程序?还有比这更优雅的事吗?


您可以让 A 上的触发器执行某些操作来提醒 B 上的触发器不需要触发。有多种想要为会话设置某种状态的想法。最简单的方法是创建一个带有布尔变量的包bypass_checks_on_b你设置为TRUE在你做之前UPDATE在 A 上,设置为FALSE一旦UPDATE完成,然后在进行验证之前检查 B 上触发器中该变量的状态。您也可以使用临时表或上下文执行类似的操作,而不是使用包。效率较低,您可能会解析 B 上的触发器内的调用堆栈,以查看 A 上的触发器是否在调用堆栈中,但这往往相当难看。

不过,我对整个架构非常谨慎。当您发现 A 上的触发器导致 B 上的触发器想要查询 A 时,几乎总是这样,您在触发器中放置了太多逻辑,并且移动会更好将该逻辑放入可以调用的存储过程层中,而不是应用程序进行直接插入或更新。当您将太多逻辑放入触发器中时,您最终会得到一个非常难以理解的系统,因为通过查看应用程序代码,各种语句具有哪些副作用并不明显。最终你会得到非常有状态的代码,其中根据调用者的不同,一段代码有很多路径。这几乎肯定意味着有些状态您没有测试或没有想到您会发现您的代码做了一些意想不到的事情。在拥有大量状态和具有大量副作用的代码库之间,您很快就可以构建本质上无法维护的代码库。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何避免触发器内的 ORA-04091 错误 的相关文章

随机推荐

  • C# 套接字和多线程

    我正在尝试了解有关 C 中的套接字和线程的更多信息 我在网上找到了很多很好的资源来帮助我入门 到目前为止我制作的程序是一个简单的 中间人 应用程序 它的设计如下 客户端 应用程序 服务器 给定以下代码 如何防止该线程以 100 CPU 运行
  • android 每个星期一或每个星期二重复闹钟

    我正在开发一个基于警报的应用程序 其中我必须根据用户输入在每个工作日重复警报 每个星期一 星期二 星期三 我用了这个片段 Intent intent new Intent context AlarmReceiver class Pendin
  • Prolog 中的错误未定义过程

    我写了一条规则 parent georgie jessy child jessy georgio 但是 当我想证明 parent georgie jessy 我收到错误 parent 2 Undefined procedure child
  • 将纯色背景颜色动画化为图像

    我有一组 div 我希望它们每个都有不同的背景颜色 而悬停时过渡到背景图像所选网址的 到目前为止 我已经成功找到了平滑颜色 gt 图像转换的代码 但这需要 HTML 中的实际 img 代码 并且我需要这些 div 因为我将在其中放入文本 有
  • 从 C# Windows 应用程序读取/写入三星 Android 手机/平板电脑

    我正在编写一个 Windows C winforms 应用程序 它将图像从 PC 复制到 Android 设备的图像文件夹 Windows 文件资源管理器给了我这个路径 Computer SCH I535 Phone Images 但我无法
  • Android Studio 无法解析fragmentActivity 和ViewPager 导入

    我遵循开发可滑动选项卡的教程 当我导入时 import android support v4 app FragmentActivity import android support v4 view ViewPager Android Stu
  • 示例:使用 AsyncTask 的 Android 双向网络套接字

    我发现的大多数 Android 网络套接字示例都是单向的 我需要一个双向数据流的解决方案 我最终了解到了 AsyncTask 此示例演示如何从套接字获取数据并将数据发送回套接字 由于接收数据的套接字具有阻塞性质 因此该阻塞需要在 UI 线程
  • 如何让 Jenkins 上的 groovy 屏蔽变量的输出,就像处理凭证一样?

    Jenkins 上的 groovy 是否有一种方法可以获取任意字符串变量 例如对另一个服务的 API 调用的结果 并让 Jenkins 在控制台输出中屏蔽它 就像它自动从凭证管理器读取的值一样 更新的解决方案 要隐藏变量的输出 您可以使用掩
  • 声明与全局、局部和静态同名的变量

    我有以下代码片段 我必须分析输出是什么 include
  • 使用 Sunspot 从 Solr 索引中排除文章草稿

    我有一个名为 Article 的索引模型 我不希望 solr 索引未发布的文章 class Article lt ActiveRecord Base searchable do text title text body end end 我怎
  • Deviseomniauthable 因“无法找到有效的路径映射”而破坏 Omniauth 身份验证

    在我的项目中 我有两种类型的用户 求职者和招聘经理 求职者没有模型 他们只能使用从第三方提供商收到的数据来申请工作 同时通过 Omniauth 进行身份验证 招聘经理的信息存储在设计用户模型中 招聘经理还必须能够使用其公司的 Google
  • mysql where语句日期问题

    希望有人能帮忙 我想做的是从数据库中提取任何给定月份的所有结果 是否可以仅使用 mysql 查询 无 php 我使用一个模板应用程序 我唯一的访问权限是通过 mysql where 语句 所以我需要从 2013 04 01 算出月份是什么
  • 求解具有变量约束的非线性方程组

    使用 fsolve 求解非线性方程组的一些假设示例 from scipy optimize import fsolve import math def equations p x y p return x y 2 4 math exp x
  • 不使用主键的映射中流畅的 NHibernate 连接表

    我正在尝试从 2 个不通过主键相关的表创建一个实体 Tables CREATE TABLE employees ssn nvarchar 9 NULL active bit NULL employee id int IDENTITY 1 1
  • Android:如何制作带有 2 行文本和 RadioButton(单选)的 AlertDialog?

    如何制作包含如下行的列表对话框 FIRST LINE OF TEXT o lt this is a RadioButton second line of text 我知道我应该使用自定义适配器 通过这些视图传递行布局 实际上 我已经这样做了
  • 更新文档时出现错误:由于值未定义,转换为字符串失败

    我有一个简单的文档 其中包含名称 必需 和描述 可选 在我的模型中 我使用有效 ID 更新文档 并传递值为未定义的描述 因为我想从文档中删除此属性 但是 我收到以下错误 消息 转换为字符串失败 路径 描述 处的值 未定义 名称 CastEr
  • Magento:如何在客户信息字段中显示客户的电话号码

    我试图让客户的电话号码显示在客户帐户信息部分下 我知道电话号码属于客户地址部分 但我正在尝试重新设计客户帐户信息的外观 我为客户 ID 添加了一个新的自定义字段 并且可以使用以下代码显示它 因为客户 ID 属于 customer entit
  • 在 cakephp 中验证输入文件

    在 cakephp 中 我试图检查文件输入字段是否附加了文件 如果没有则输出错误 我已经在其他领域做到了这一点 但似乎无法让它在该领域发挥作用 这是模型 array notempty uploadeduploaded file gt arr
  • 将输入的数据存储在数组中[重复]

    这个问题在这里已经有答案了 我是 C 初学者 如果我的问题很蹩脚 请不要介意 在我编写的这个程序中 当我第一次使用 for 循环时 我预计数组中仅存储 3 个值 但它存储 4 个值 并且在下一个 for 循环中按预期显示 3 个值 我的问题
  • 如何避免触发器内的 ORA-04091 错误

    我在表 A 上有一个更新后触发器 触发器 A 可以对表 B 进行更改 我在表 B 上还有一个更新后触发器 触发器 B 它不进行任何更改 但查询表 A 以对非规范化进行一些健全性检查 因此触发器 B 可以通过以下两种方式之一触发 如果我直接更