GO är inte ett T-SQL-kommando. Är en batchavgränsare. Klientverktyget (SSM, sqlcmd, osql etc) använder det för att effektivt klippa filen vid varje GO och skicka de enskilda batcharna till servern. Så uppenbarligen kan du inte använda GO inuti IF, och du kan inte heller förvänta dig att variabler ska sträcka sig över satser.
Du kan inte heller fånga undantag utan att leta efter XACT_STATE()
för att säkerställa att transaktionen inte är dömd.
Att använda GUID för ID är alltid åtminstone misstänkt.
Använder NOT NULL-begränsningar och tillhandahåller en standard "guide" som '{00000000-0000-0000-0000-000000000000}'
kan inte heller vara korrekt.
Uppdaterad:
- Dela upp ALTER och UPDATE i två omgångar.
- Använd sqlcmd-tillägg för att bryta skriptet vid fel. Detta stöds av SSMS när sqlcmd-läget är på , sqlcmd, och är trivialt för att stödja det i klientbibliotek också:dbutilsqlcmd .
- använd
XACT_ABORT
för att tvinga fel att avbryta batchen. Detta används ofta i underhållsskript (schemaändringar). Lagrade procedurer och applikationslogikskript använder i allmänhet TRY-CATCH-block istället, men med lämplig försiktighet:Undantagshantering och kapslade transaktioner .
exempelskript:
: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
Endast ett framgångsrikt skript når COMMIT
. Alla fel kommer att avbryta skriptet och återställa.
Jag använde COLUMN PROPERTY
för att kontrollera kolumnexistensen kan du använda vilken metod du vill istället (t.ex. slå upp sys.columns
).