2 votes

La table temporaire globale avec l'option "On commit delete rows" ne contient aucune donnée.

J'ai une table temporaire globale (GTT) définie dans un script de création utilisant l'option de suppression des rangs lors du commit. Je voulais pouvoir faire en sorte que différents utilisateurs voient leurs propres données dans la GTT et non les données des sessions d'autres personnes. Cela a parfaitement fonctionné dans notre environnement de test.

Mais ensuite, j'ai déployé GTT dans le cadre d'une mise à jour des fonctionnalités de la base de données d'un client. Le client m'a appelé, bouleversé et inquiet, car le GTT ne contenait plus aucune donnée et il ne savait pas pourquoi.

Plus précisément, si quelqu'un l'a fait :

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

la base de données répondrait :

1 row inserted. 

Cependant, si le même utilisateur final a essayé :

select * from my_GTT

La base de données répondrait :

0 rows returned.

Ce problème se produit sur le site du client, et nous ne pouvons pas le reproduire en interne. Quelle pourrait être la cause de ce comportement ?

3voto

Stano Januschke Points 31

ON COMMIT DELETE ROWS = données en une seule transaction

ON COMMIT PRESERVE ROWS = données dans une session de base de données (un utilisateur avec 2 sessions = 2 sessions = contenu différent)

Si le GTT est défini avec ON COMMIT DELETE ROWS Si la table est vide, elle le sera après tout commit explicite ou implicite (= commit implicite = après toute commande DLL, y compris par exemple truncate table, alter index, add partition, modify column, exchange partition) :

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 

Si le GTT est défini avec ON COMMIT PRESERVE ROWS il conservera les données jusqu'à la fin de la session :

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

2voto

Damien_The_Unbeliever Points 102139

Avez-vous activé un paramètre dans votre environnement cible pour que chaque déclaration s'exécute automatiquement ?

(Mon expérience se situe dans SQL Server, où c'est le cas par défaut, mais je crois savoir que dans Oracle, le défaut est de garder la transaction ouverte jusqu'à un commit explicite. Attention, je n'ai pas touché à Oracle depuis ~2000)

0voto

Gary Myers Points 24819

Je pense que Damien a raison et qu'il y a un autocommit. La seule autre option à laquelle je peux penser est une sorte de problème de pool de connexion (c'est-à-dire que la sélection est effectuée à partir d'une session distincte de celle de l'insertion).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X