是否允许在流水线PL/SQL表函数中使用SELECT?

是否允许在流水线PL/SQL表函数中使用SELECT?,sql,oracle,plsql,dml,pipelined-function,Sql,Oracle,Plsql,Dml,Pipelined Function,管道函数的文档指出,当DML用于SQL语句(通常是SELECT)时,不允许使用DML,在大多数示例中,管道函数用于数据生成或转换(接受custor作为参数),但不发出任何DML语句 现在,从技术上讲,可以使用SELECTs而不会出现来自Oracle的任何错误(不会发生)。然而,我有经验重复选择的奇怪行为;尽管没有使用PRAGMA AUTONOMOUS\u事务,但是SELECT检索的行似乎并不总是考虑当前本地事务,这对我来说就像一个bug。更令人不安的是,当使用分布式事务(例如通过ORAMTS而不

管道函数的文档指出,当DML用于SQL语句(通常是
SELECT
)时,不允许使用DML,在大多数示例中,管道函数用于数据生成或转换(接受custor作为参数),但不发出任何DML语句

现在,从技术上讲,可以使用SELECTs而不会出现来自Oracle的任何错误(不会发生)。然而,我有经验重复选择的奇怪行为;尽管没有使用
PRAGMA AUTONOMOUS\u事务
,但是
SELECT
检索的行似乎并不总是考虑当前本地事务,这对我来说就像一个bug。更令人不安的是,当使用分布式事务(例如通过ORAMTS而不是本地事务)时,会使用事务

编辑:事实证明,奇怪的效果似乎与查询中的某些WITH语句有关,有时有效,有时无效(取决于Oracle optimizer的当前状态,至少在10g中是这样)。在某些情况下,我得到了一个ORA-32036,然后它再次没有发生,根本没有更改代码。现在看来,ORA-32036有时失败的查询也是无法使用正确事务的查询,并且可能与流水线函数无关

因此,我的具体问题是:

  • 是否有任何官方声明(最好是官方声明)允许管道表函数中的
    SELECT
    s,以及它们的事务上下文是什么

  • 是否有另一种模块化常用查询的方法可以在SQL语句中使用(就像使用
    table()
    的表函数一样)

  • 有没有人也经历过这样的行为,也许知道得更多?我已经研究了metalink,但不幸的是,我没有找到关于这个主题的任何具体内容

  • 通常DML限制只涉及修改(更新、删除…)语句,所以SELECT应该是OK。我将尝试从Oracle中找到一个特定的语句

  • 视图将是模块化常用查询的第一个工具

  • 与视图相比,函数有一个缺点:如果从另一个SELECT调用它们,则它们不会在与主SELECT相同的时间点执行。对SELECT的每次调用都是一致的,但由于SELECT在函数代码中,而不是在主SQL中,因此可能会返回不一致的结果。对于视图和子选择,这是不可能的:如果一个大语句调用一个视图,那么该视图是在与主查询相同的时间点生成的

  • 更新:关于您对参数化查询的评论


    您可以构建参数化视图,即依赖于执行前设置的变量的视图。显示如何使用
    userenv('client\u info')
    dbms\u session.set\u context

    谢谢你的回复。关于2,问题是在处理递归之前需要考虑一些参数。事实上,我们有一个历史化的图连接列表,它们有一个创建和删除日期/时间(null表示已删除,表示未删除)。现在,我必须按照特定的日期/时间重新构建图形,因此我目前不知道如何使用视图解决此问题。基本上,如果你知道T-SQL,我想用一种方法来实现一些类似于在那里找到的内联表函数的东西,我发现最接近的是流水线表函数。我进行了一些测试,这些测试包括打开连接、启动事务、插入数据(使用insert)、调用使用该函数的SP以及显示结果。这些测试失败,即使它们没有与任何其他测试同时运行,而且即使在这种情况下,函数也足够粗糙,并且在单个语句中执行查询(带有多个with),因此结果应该是一致的。但是谢谢你指出这点。@Lucero:我更新了关于2的答案。关于您对第3点的评论,如果您的函数不是一个自治事务,那么它应该位于同一事务上,并查看与主查询相同的数据。但有两个问题:1)您的流水线函数是从INSERT调用的还是从另一个SELECT调用的?2) 如果非管道化重写函数,是否会出现同样的不一致性?@Vincent,我知道这项技术(有人告诉我,我应该更喜欢sys_上下文而不是userenv,但基本概念是相同的)。然而,由于我有6个参数,我需要传递到“参数化视图”,据我所知,它们只返回varchar,这意味着它们必须被转换为要比较的列的类型(在我的例子中是2个datetime和4个raw(16)guid),我担心这不会非常有效。但是,性能非常关键。回答您的问题:仅在SELECT中,但将其作为引用光标从SP返回。尚未尝试非管道化,将尝试。@Vincent,关于非管道化,这是一个比我预期的更大的更改。。。Oracle声明“注意:返回包级别类型的表函数必须是管道化的。”