Oracle WITH and MATERIALIZE hint充当函数的自治事务

Oracle WITH and MATERIALIZE hint充当函数的自治事务,oracle,function,common-table-expression,Oracle,Function,Common Table Expression,在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

在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 bug还是打算这样工作?(为什么?)
为什么只有当WITH与具体化提示和函数调用相结合时,它才会这样工作?

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

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


有关更多信息,请参阅MOS文档15889476.8和13253977.8。您可能需要与Oracle支持部门联系,以确认这是您看到的问题,但它看起来非常类似。

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

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


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

无法在Oracle 12c上复制,在我的情况下,last select返回1。我猜Peti在12.1.0.1上,Husqvik在12.1.0.2上?看起来像个bug。但通常情况下,预期行为是未定义的。解决方案是永远不要使用递归SQL。函数
SELECT count(1)
在不同的SCN上下文中运行,因此它可以看到虚拟数据。尝试使用
SERIALIZABLE
隔离级别。或者也可以尝试选择实际数据库SCN。当然,您的发现是相反的,您没有看到您应该看到的数据。这里看起来与此类似:正如Alex指出的,在与此相关的问题上有一个已注册的Bug。所以是的-这似乎是一个与未记录的Materialize提示相关的Oracle错误…无法在Oracle 12c上复制,在我的情况下,last select返回1。我猜Peti在12.1.0.1上,Husqvik在12.1.0.2上?它看起来像一个错误。但通常情况下,预期行为是未定义的。解决方案是永远不要使用递归SQL。函数
SELECT count(1)
在不同的SCN上下文中运行,因此它可以看到虚拟数据。尝试使用
SERIALIZABLE
隔离级别。或者也可以尝试选择实际数据库SCN。当然,您的发现是相反的,您没有看到您应该看到的数据。这里看起来与此类似:正如Alex指出的,在与此相关的问题上有一个已注册的Bug。所以是的-这似乎是一个与未记录的物化提示相关的Oracle错误。。。