我回顾了Oracle(11g)开发,几年后我的团队项目需要帮助。我们正在尝试实现一个POC,其中任何添加/删除列将丢弃并重新创建一个有害的视图。 View是指用于生成别名和列选择的Mapping表。
我的解决方案:
- 1。扫描添加列,丢弃列的DDL触发器 - >标识列名称 - >更新Field_Map表 - > Drops View - >使用Field_Map表别名创建视图
挑战:由于DDL中的视图创建而收到递归触发错误
- 2。 DDL触发器扫描添加列,拖放列 - > - >更新字段映射表 - >将已识别的列名称,表格写入Audit_DDL表 - > Audit_DDL表上的DML触发器触发 - >禁用DDL触发器(以避免递归) - >丢弃视图 - >使用Field_Map表别名
创建视图挑战:收到递归触发错误。我认为,它仍然将整个流程视为一个交易。在DML触发器下分离创建视图没有帮助。
所以,我正在考虑替代方案:
- 3。存储触发器,Schema1中的表和View Schema2。我期待,这可以避免递归,因为创建视图现在将发生在schema2上,触发器构建在schema1上。
- 4。创建一个存储过程,扫描Audit_DDL条目(来自#2)以更新表,列。为已处理的Audit_DDL条目创建视图和标记。每小时工作现在运行此程序。
有什么建议吗?在此先感谢帮助我!
答案 0 :(得分:1)
如果要从触发器执行DDL,则需要异步。最简单的解决方案是DDL触发器使用DBMS_JOB
包提交作业,该包将执行您想要执行的任何DDL。在触发事务(ALTER
语句)提交之前,该作业不会运行。但它可能会在几秒钟后运行(取决于正在运行的其他作业数量,允许的作业数量等)。是否构建要在触发器中执行的DDL语句并将其传递给作业,或者是否将作业所需的信息存储在表中并传递某种键(即对象名称)并让作业汇编DDL语句是一个实现细节。
话虽如此,这似乎是一个非常糟糕的架构。如果要添加或删除列,那么应该通过适当的更改控制过程。如果更改正在进行更改控制,则应该很容易在同一脚本中包含对视图的更改。依赖于视图的应用程序应作为更改控制过程的一部分进行测试。如果更改没有通过更改控制并且列被添加到视图中或从视图中删除,那么您在业务流程中遇到了更大的问题并且您很可能会导致一个或多个应用程序陷入奇怪的陷阱在看似模糊不清的时间点上的精彩方式。