问题描述
-
通常,DML限制仅涉及修改(UPDATE,DELETE …)语句,因此SELECT应该可以。我将尝试从Oracle查找特定声明。
-
函数在视图方面有一个缺点:如果从另一个SELECT调用它们,则它们不会在与主SELECT相同的时间点执行。每次对SELECT的调用都是一致的,但是由于SELECT在函数代码中而不在主sql中,因此您可能返回不一致的结果。对于视图和子选择,这是不可能的:如果一个大语句调用一个视图,则该视图将在与主查询相同的时间点构建。
您可以构建参数化视图,即依赖于执行前设置的变量的视图。这是AskTom上的示例,展示了如何使用userenv('client_info')
或来实现dbms_session.set_context
。
解决方法
有关流水线函数的文档说,在SQL语句(通常是a
SELECT
)中使用DML时是不允许的,并且在大多数示例中,流水线函数用于数据生成或转换(接受custor作为参数),但不发布任何DML。 DML语句。
现在,从技术上讲,可以使用SELECT而不会出现Oracle的任何错误(不会发生ORA 14551)。但是,我有选择的可重现的奇怪行为的经验;即使PRAGMA
AUTONOMOUS_TRANSACTION
是 没有 被使用,被检索的行SELECT
似乎 并不
总是把当前本地事务考虑进去,这感觉就像我的错误。更令人不安的是,当使用分布式事务(例如,通过ORAMTS而不是本地事务)时,会使用该事务。
编辑:
事实证明,这种奇怪的效果似乎与查询中的某些WITH语句有关,有时可能起作用,有时却不起作用(取决于Oracle优化器的当前状态,至少在10g中)。在某些情况下,我得到了ORA-32036,然后再次发生,即使不更改代码也不会发生。现在看来,有时因ORA-32036而失败的查询也是那些也未能使用正确事务的查询,并且它可能与流水线功能无关。
所以我的具体问题是:
-
是否有任何(最好是官方的)声明是否
SELECT
允许流水线表函数中的以及它们的事务上下文是什么? -
有没有其他方法可以模块化可在SQL语句中使用的常用查询(就像表函数可以使用一样
TABLE()
)? -
有没有人也经历过这种行为,也许对此有更多了解?我已经研究了metalink,但是不幸的是,我没有找到关于该主题的任何具体信息。