管道函数的文档说,在SQL语句(通常是SELECT
)中使用DML时不允许使用DML,并且在大多数示例中,管道函数用于数据生成或转换(接受客户端)作为参数),但不发布任何DML语句。
现在,从技术上讲,可以使用SELECT而不会出现Oracle的任何错误(ORA 14551不会发生)。但是,我有经验重现奇怪的选择行为;即使PRAGMA AUTONOMOUS_TRANSACTION
不正在使用,SELECT
检索到的行似乎不总是考虑到当前的本地交易,感觉就像给我一个bug。更令人不安的是,当使用分布式事务时(例如通过ORAMTS而不是本地事务),使用事务。
编辑:事实证明,奇怪的效果似乎与查询中的一些WITH语句有关,有时可以工作,有时不工作(取决于Oracle优化器的当前情绪,至少在10G)。在某些情况下,我得到一个ORA-32036,然后再没有发生,根本没有改变代码。现在,看起来ORA-32036有时失败的查询是那些也无法使用正确事务的查询,它可能与流水线函数无关。
所以我的具体问题是:
是否有任何(最好是官方的)声明是否允许管道表函数中的SELECT
以及它们的事务上下文是什么?
是否存在另一种模块化常用查询的方法,可以在SQL语句中使用(就像表函数可以与TABLE()
一样)?
有没有人也经历过这样的行为并且可能对此有更多了解吗?我调查了metalink,但不幸的是我没有找到关于这个话题的具体内容。
答案 0 :(得分:1)
通常DML限制只涉及修改(UPDATE,DELETE ...)语句,所以SELECT应该没问题。我将尝试从Oracle中找到一个特定的声明。
视图将是您模块化常用查询的第一个工具。
函数比视图有缺点:如果从另一个SELECT调用它们,它们不会在与主SELECT相同的时间点执行。每次调用SELECT都是一致的,但由于SELECT在函数代码中,而不在主SQL中,因此可能会返回不一致的结果。这对于视图和子选择是不可能的:如果一个大语句调用视图,则视图与主查询在相同的时间点构建。
更新:关于您对参数化查询的评论
您可以构建参数化视图,即依赖于执行前设置的变量的视图。 Here is an example on AskTom显示了如何使用userenv('client_info')
或dbms_session.set_context
执行此操作。