GO ist kein T-SQL-Befehl. Ist ein Stapeltrennzeichen. Das Client-Tool (SSM, sqlcmd, osql usw.) verwendet es zum effektiven Schneiden die Datei bei jedem GO und sende die einzelnen Batches an den Server. Sie können also offensichtlich weder GO innerhalb von IF verwenden, noch können Sie erwarten, dass Variablen den Geltungsbereich über Batches erstrecken.
Außerdem können Sie keine Ausnahmen abfangen, ohne nach XACT_STATE()
um sicherzustellen, dass die Transaktion nicht zum Scheitern verurteilt ist.
Die Verwendung von GUIDs für IDs ist immer zumindest verdächtig.
Verwenden von NOT NULL-Einschränkungen und Bereitstellen einer Standard-'Guid' wie '{00000000-0000-0000-0000-000000000000}'
kann auch nicht stimmen.
Aktualisiert:
- Trennen Sie ALTER und UPDATE in zwei Stapel.
- Verwenden Sie sqlcmd-Erweiterungen, um das Skript bei einem Fehler zu unterbrechen. Dies wird von SSMS unterstützt, wenn der sqlcmd-Modus aktiviert ist , sqlcmd, und es ist trivial, es auch in Client-Bibliotheken zu unterstützen:dbutilsqlcmd .
- verwenden Sie
XACT_ABORT
um einen Fehler zu erzwingen, um den Stapel zu unterbrechen. Dies wird häufig in Wartungsskripten (Schemaänderungen) verwendet. Gespeicherte Prozeduren und Anwendungslogik-Skripte verwenden im Allgemeinen stattdessen TRY-CATCH-Blöcke, aber mit angemessener Sorgfalt:Ausnahmebehandlung und verschachtelte Transaktionen .
Beispielskript:
: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
Nur ein erfolgreiches Skript erreicht den COMMIT
. Jeder Fehler bricht das Skript ab und führt ein Rollback durch.
Ich habe COLUMNPROPERTY
verwendet
Um das Vorhandensein von Spalten zu überprüfen, können Sie stattdessen eine beliebige Methode verwenden (z. B. lookup sys.columns
).