【问题标题】:Oracle WITH and MATERIALIZE hint acts as autonomous transaction for functionsOracle WITH 和 MATERIALIZE 提示充当函数的自治事务
【发布时间】:2016-03-03 12:52:01
【问题描述】:

在 Oracle 12c 中,如果我在使用 WITH..AS 部分中的 MATERIALIZE 提示的查询中调用函数,则函数调用的行为类似于自主事务:

DROP TABLE my_table;

CREATE TABLE my_table (
    my_column NUMBER
);

-- Returns number of records in table 
CREATE OR REPLACE FUNCTION my_function 
RETURN INTEGER
IS
    i INTEGER;
BEGIN
    SELECT COUNT(1) INTO i FROM my_table;
    RETURN i;
END;
/

-- Inserts one record to table 
INSERT INTO my_table (my_column) VALUES (9);

-- Returns number of records in table. This works correctly, returns 1
SELECT COUNT(1) AS "use simple select" FROM my_table;

-- Returns number of records in table. This works correctly, returns 1
WITH x AS (
    SELECT /*+ MATERIALIZE */ COUNT(1) AS "use WITH, MATERIALIZE" FROM my_table
)
SELECT * FROM x;

-- Returns number of records in table. This works correctly, returns 1
SELECT my_function AS "use FUNCTION" FROM dual;

-- Returns number of records in table. This works INCORRECTLY, returns 0. 
-- Function is called in autonomous transaction?
WITH x AS (
    SELECT /*+ MATERIALIZE */ my_function "use WITH,MATERIALIZE,FUNCTION" FROM dual
)
SELECT * FROM x;

ROLLBACK;

有人知道这是什么原因吗?它是 Oracle 错误还是打算像这样工作? (为什么?) 为什么只有当 WITH 与 MATERIALIZED 提示和 FUNCTION 调用结合使用时才会这样?

【问题讨论】:

  • 无法在 Oracle 12c 上重现,在我的情况下,最后一次选择返回 1。
  • 我猜 Peti 在 12.1.0.1 上,而 Husqvik 在 12.1.0.2 上?
  • 它看起来像一个错误。但通常 AFAIK 预期的行为是未定义的。解决方案是永远不要使用递归 SQL。 SELECT count(1) 函数在不同的 SCN 上下文中运行,因此它可以看到幻像数据。尝试使用SERIALIZABLE 隔离级别。或者尝试也选择实际的数据库 SCN。当然,你的发现是相反的,你看不到应该看到的数据。
  • 在这里看起来与此类似:hourim.wordpress.com/2012/07/23/materialize-hint-again 并且正如 Alex 指出的那样,在与此相关的问题上存在一个已注册的错误。所以是的 - 它似乎是与未记录的 Materialize 提示相关的 Oracle 错误......

标签: oracle function common-table-expression


【解决方案1】:

这看起来像错误 15889476,“游标持续时间临时表和在活动事务上运行的函数的错误结果”;和 13253977“游标持续时间临时表和在活动事务上运行的 PLSQL 函数出现错误结果或错误”。

我可以在 11.2.0.3 上重现,但不能在 11.2.0.4 上重现;从 Husqvik 的评论来看,它似乎没有在 12.1.0.2 上重现。这与错误文档中的受影响版本和修复优先包含的信息一致。

有关详细信息,请参阅 MOS 文档 15889476.8 和 13253977.8。您可能需要联系 Oracle 支持以确认这是您遇到的问题,但看起来非常相似。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 2012-03-23
    • 1970-01-01
    • 2021-10-13
    • 2014-07-09
    • 1970-01-01
    • 2022-01-04
    相关资源
    最近更新 更多