Freitag, Juni 14, 2013

DDL und Rollback

Kann man ein DDL-Kommando über ROLLBACK wieder rückgängig machen? Die Antwort auf diese Frage lautet erstaunlicherweise mal wieder: it depends. Abhängig ist die Antwort in diesem Fall von der verwendeten Datenbank. Für Oracle ist der Fall ganz einfach: ein TRUNCATE TABLE zum Beispiel ist DDL und DDL kann nicht zurückgerollt werden, da darin in implizites Commit enthalten ist:

-- 11.2.0.1
drop table t;

create table t(a number);  
insert into t(a) values(1);  
commit;  

select data_object_id 
  from user_objects
 where object_name = 'T';

DATA_OBJECT_ID
--------------
        102347

truncate table t;  
rollback;  

select data_object_id 
  from user_objects
 where object_name = 'T';

DATA_OBJECT_ID
--------------
        102348

select * from t;  

Es wurden keine Zeilen ausgewählt

Im Fall von Truncate vergibt Oracle dabei auch eine neue data_object_id: intern wird also offenbar eine leere Kopie der behandelten Tabelle angelegt und gegen das Original ausgetauscht (und die Änderung der data_object_id ergibt sich auch, wenn man das Truncate mit einem "reuse storage" verwendet).

Mit dieser Sicht der Dinge steht Oracle aber relativ alleine da, denn viele andere RDBMS haben keine Einwände dagegen, DDL wieder zurückzurollen.

-- SQL Server 2008  
drop table t; 
 
create table t(a int);   
insert into t(a) values(1);  

begin transaction  
truncate table t;  
rollback;  

select * from t;   
  a  
---  
  1  

Welche der beiden Interpretationen ist nun die korrekte - und entspricht genauer den Forderungen irgendeines ANSI SQL Standards? Ich weiß es nicht. Aber merken sollte man sich jedenfalls, dass DDL sich in unterschiedlichen RDBMS unterschiedlich verhält, wozu man in einem Thread bei dba.stackexchange.com und im posgresql-Wiki noch ein paar zusätzliche Details findet.

Keine Kommentare:

Kommentar veröffentlichen