web-dev-qa-db-fra.com

Est-il possible de restaurer les instructions CREATE TABLE et ALTER TABLE dans les principales bases de données SQL?

Je travaille sur un programme qui émet du DDL. J'aimerais savoir si CREATE TABLE et DDL similaire peuvent être restaurés

  • Postgres
  • MySQL
  • SQLite
  • et al

Décrivez comment chaque base de données traite les transactions avec DDL.

103
joeforker

http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis fournit un aperçu de ce problème du point de vue de PostgreSQL.

Est-ce que DDL est transactionnel selon ce document?

  • PostgreSQL - oui
  • MySQL - non; DDL provoque une validation implicite
  • Oracle Database 11g version 2 et ultérieure - par défaut, non, mais une alternative appelée redéfinition basée sur l'édition existe
  • Anciennes versions d'Oracle - non; DDL provoque une validation implicite
  • SQL Server - oui
  • Sybase Adaptive Server - oui
  • DB2 - oui
  • Informix - oui
  • Firebird (Interbase) - oui

SQLite semble également avoir une DDL transactionnelle. J'ai pu ROLLBACK un CREATE TABLE déclaration dans SQLite. C'est CREATE TABLE La documentation ne mentionne pas de "pièges" transactionnels particuliers.

138
joeforker

PostgreSQL a une DDL transactionnelle pour la plupart des objets de base de données (certainement des tables, des index, etc., mais pas des bases de données, des utilisateurs). Cependant, pratiquement tous les DDL obtiendront un ACCESS EXCLUSIVE verrouille sur l'objet cible, le rendant complètement inaccessible jusqu'à la fin de la transaction DDL. De plus, toutes les situations ne sont pas gérées correctement. Par exemple, si vous essayez de sélectionner dans la table foo alors qu'une autre transaction la supprime et crée une table de remplacement foo, la transaction bloquée sera finalement reçue. une erreur plutôt que de trouver la nouvelle table foo. (Edit: cela a été corrigé dans ou avant PostgreSQL 9.3)

CREATE INDEX ... CONCURRENTLY est exceptionnel, il utilise trois transactions pour ajouter un index à une table tout en autorisant les mises à jour simultanées. Il ne peut donc pas être exécuté dans une transaction.

De plus, la commande de maintenance de la base de données VACUUM ne peut pas être utilisée dans une transaction.

28
araqnid

Bien qu'il ne s'agisse pas à proprement parler d'une "annulation", dans Oracle, la commande FLASHBACK peut être utilisée pour annuler ces types de modifications, si la base de données a été configurée pour la prendre en charge.

4
Dave Costa

Cela ne peut pas être fait avec MySQL , cela semble très bête, mais vrai ... (selon la réponse acceptée)

"L'instruction CREATE TABLE dans InnoDB est traitée comme une transaction unique. Cela signifie qu'un ROLLBACK de l'utilisateur n'annule pas les instructions CREATE TABLE que l'utilisateur a effectuées lors de cette transaction."

https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

Essayé de différentes façons et il ne veut tout simplement pas revenir en arrière.

La solution consiste simplement à définir un indicateur d'échec et à effectuer une opération "drop table tblname" si l'une des requêtes échoue.

2
Robert Sinclair

On dirait que les autres réponses sont plutôt dépassées.

À partir de 2019:

  • Postgres a pris en charge la DDL transactionnelle pour de nombreuses versions.
  • SQLite a pris en charge le DDL transactionnel pour de nombreuses versions.
  • MySQL a supporté Atomic DDL depuis 8. (publié en 2018).
1
PaulMest