Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Ajouter une colonne à la table, puis la mettre à jour dans la transaction

GO n'est pas une commande T-SQL. Est un délimiteur de lot. L'outil client (SSM, sqlcmd, osql, etc.) l'utilise pour couper efficacement le fichier à chaque GO et envoyer au serveur les lots individuels. Donc, évidemment, vous ne pouvez pas utiliser GO à l'intérieur de IF, et vous ne pouvez pas non plus vous attendre à ce que les variables s'étendent sur plusieurs lots.

De plus, vous ne pouvez pas intercepter les exceptions sans vérifier le XACT_STATE() pour s'assurer que la transaction n'est pas vouée à l'échec.

L'utilisation de GUID pour les identifiants est toujours au moins suspecte.

Utiliser les contraintes NOT NULL et fournir un 'guid' par défaut comme '{00000000-0000-0000-0000-000000000000}' ne peut pas non plus être correct.

Mis à jour :

  • Séparez ALTER et UPDATE en deux lots.
  • Utilisez les extensions sqlcmd pour casser le script en cas d'erreur. Ceci est pris en charge par SSMS lorsque le mode sqlcmd est activé , sqlcmd, et il est également facile de le prendre en charge dans les bibliothèques clientes :dbutilsqlcmd .
  • utiliser XACT_ABORT pour forcer l'erreur à interrompre le lot. Ceci est fréquemment utilisé dans les scripts de maintenance (changements de schéma). Les procédures stockées et les scripts de logique d'application utilisent en général des blocs TRY-CATCH à la place, mais avec les précautions nécessaires :Gestion des exceptions et transactions imbriquées .

exemple de script :

:on error exit

set xact_abort on;
go

begin transaction;
go

if columnproperty(object_id('Code'), 'ColorId', 'AllowsNull') is null
begin
    alter table Code add ColorId uniqueidentifier null;
end
go

update Code 
  set ColorId = '...'
  where ...
go

commit;
go

Seul un script réussi atteindra le COMMIT . Toute erreur annulera le script et la restauration.

J'ai utilisé COLUMNPROPERTY pour vérifier l'existence de la colonne, vous pouvez utiliser la méthode de votre choix à la place (par exemple, lookup sys.columns ).