2

我使用在提交时删除行的选项在创建脚本中定义了一个全局临时表 (GTT)。我希望能够让不同的用户在 GTT 中看到他们自己的数据,而不是其他人会话的数据。这在我们的测试环境中完美运行。

但后来,我部署了 GTT 作为客户数据库功能更新的一部分。客户打电话给我,非常沮丧和担心,因为 GTT 不再保存任何数据,他们不知道为什么。

具体来说,如果有人这样做:

insert into my_GTT (description) values ('Happy happy joy joy')

数据库将响应:

1 row inserted. 

但是,如果同一最终用户尝试:

select * from my_GTT

数据库将响应:

0 rows returned.

此问题发生在客户端站点上,我们无法在内部重现它。什么可能导致这种行为?

4

3 回答 3

3

ON COMMIT DELETE ROWS= 一笔交易中的数据

ON COMMIT PRESERVE ROWS= 一个数据库会话中的数据(一个用户有 2 个会话 = 2 个会话 = 不同的内容)

如果 GTT 用 定义ON COMMIT DELETE ROWS,则在任何显式提交或隐式提交之后它将为空(= 隐式提交 = 在任何 DLL 命令之后,包括例如截断表、更改索引、添加分区、修改列、交换分区):

CREATE GLOBAL TEMPORARY TABLE GTT__TEST (A NUMBER) ON COMMIT DELETE ROWS;
INSERT INTO GTT__TEST VALUES (1); 
SELECT * FROM GTT__TEST; -- 1 ROW; 
COMMIT; -- commit = delete rows
SELECT * FROM GTT__TEST; -- 0 ROWS; 
INSERT INTO GTT__TEST VALUES (1); 
SELECT * FROM GTT__TEST; -- 1 ROW; 
ALTER TABLE GTT__TEST MODIFY A NOT NULL; -- DLL = commit = delete rows
SELECT * FROM GTT__TEST; -- 0 ROWS 

如果 GTT 定义为ON COMMIT PRESERVE ROWS,它将保存数据直到会话结束:

DROP TABLE GTT__TEST; 
CREATE GLOBAL TEMPORARY TABLE GTT__TEST (A NUMBER) ON COMMIT PRESERVE ROWS;
INSERT INTO GTT__TEST VALUES (1); 
SELECT * FROM GTT__TEST; -- 1 ROW 
COMMIT; 
SELECT * FROM GTT__TEST; -- 1 ROW
于 2014-12-12T10:28:39.343 回答
2

您是否在目标环境中打开了某些设置,其中每个语句都是自动提交的?

(我的经验是在 SQL Server 中,这是默认设置,但我理解在 Oracle 中,默认设置是在明确提交之前保持事务打开。请注意,自 2000 年以来我没有接触过 Oracle)

于 2010-04-23T06:46:48.280 回答
0

我认为 Damien 是对的,并且有一个自动提交。我能想到的唯一其他选择是某种连接池问题(即选择是从单独的会话到插入完成的)

于 2010-05-02T23:03:30.517 回答