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
).