Глобальная временная таблица с «При удалении строк при фиксации» не содержит никаких данных - PullRequest
2 голосов
/ 23 апреля 2010

У меня есть глобальная временная таблица (GTT), определенная в сценарии создания с использованием опции удаления строк при фиксации.Я хотел, чтобы разные пользователи видели свои собственные данные в GTT, а не данные других сессий.Это отлично работало в нашей тестовой среде.

Но затем я развернул GTT как часть обновления функциональности базы данных клиента.Клиент вызвал меня все расстроенные и обеспокоенные, потому что GTT больше не держал никаких данных, и они не знали почему.

В частности, если кто-то сделал:

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

база данных ответит:

1 row inserted. 

Однако, если тот же конечный пользователь попытается:

select * from my_GTT

База данных ответит:

0 rows returned.

Эта проблемапроисходит на сайте клиента, и мы не можем воспроизвести его дома.Что может быть причиной такого поведения?

Ответы [ 3 ]

3 голосов
/ 12 декабря 2014

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
2 голосов
/ 23 апреля 2010

Есть ли у вас какие-либо настройки, включенные в вашей целевой среде, где каждый оператор автоматически коммитится?

(Мой опыт работы с SQL Server, где так по умолчанию, но я понимаю, что в Oracle по умолчаниюдержать транзакцию открытой до явного принятия. Имейте в виду, я не касался Oracle с 2000 года

0 голосов
/ 03 мая 2010

Я думаю, что Дэмиен прав, и есть автокоммит.Единственный другой вариант, который я могу придумать, - это проблема с пулом соединений (т. Е. Выбор выполняется из отдельного сеанса для вставки)

...