Oracle WITH 和 MATERIALIZE 提示充当函数的自治事务
Oracle WITH and MATERIALIZE hint acts as autonomous transaction for functions
在 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 hint和FUNCTION call时才会这样?
这看起来像错误 15889476,"Wrong results with cursor-duration temp table and function running on an active transaction";和 13253977 "Wrong results or error with cursor-duration temp table and PLSQL function running on an active transaction".
我可以在 11.2.0.3 上重现,但不能在 11.2.0.4 上重现;从 Husqvik 的评论来看,它似乎没有在 12.1.0.2 上重现。这与错误文档中受影响的版本和修复优先包含的信息一致。
有关详细信息,请参阅 MOS 文档 15889476.8 和 13253977.8。您可能需要联系 Oracle 支持以确认这是您遇到的问题,但它看起来非常相似。
在 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 hint和FUNCTION call时才会这样?
这看起来像错误 15889476,"Wrong results with cursor-duration temp table and function running on an active transaction";和 13253977 "Wrong results or error with cursor-duration temp table and PLSQL function running on an active transaction".
我可以在 11.2.0.3 上重现,但不能在 11.2.0.4 上重现;从 Husqvik 的评论来看,它似乎没有在 12.1.0.2 上重现。这与错误文档中受影响的版本和修复优先包含的信息一致。
有关详细信息,请参阅 MOS 文档 15889476.8 和 13253977.8。您可能需要联系 Oracle 支持以确认这是您遇到的问题,但它看起来非常相似。