GO nie jest poleceniem T-SQL. Jest separatorem partii. Narzędzie klienta (SSM, sqlcmd, osql itp.) używa go do skutecznego cięcia plik przy każdym GO i wyślij na serwer poszczególne partie. Więc oczywiście nie możesz używać GO wewnątrz IF, ani nie możesz oczekiwać, że zmienne będą obejmowały zakres w partiach.
Ponadto nie można przechwytywać wyjątków bez sprawdzenia XACT_STATE()
aby upewnić się, że transakcja nie jest skończona.
Używanie identyfikatorów GUID do identyfikatorów jest zawsze co najmniej podejrzane.
Używanie ograniczeń NOT NULL i dostarczanie domyślnego 'guid', takiego jak '{00000000-0000-0000-0000-000000000000}'
również nie może być poprawne.
Zaktualizowano:
- Rozdziel ALTER i UPDATE na dwie partie.
- Użyj rozszerzeń sqlcmd, aby przerwać skrypt w przypadku błędu. Jest to obsługiwane przez SSMS, gdy włączony jest tryb sqlcmd , sqlcmd i obsługa go również w bibliotekach klienckich jest trywialna:dbutilsqlcmd .
- użyj
XACT_ABORT
aby zmusić błąd do przerwania partii. Jest to często używane w skryptach konserwacyjnych (zmiany schematu). Procedury składowane i skrypty logiki aplikacji zazwyczaj używają bloków TRY-CATCH, ale z należytą ostrożnością:Obsługa wyjątków i zagnieżdżone transakcje .
przykładowy skrypt:
: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
Tylko udany skrypt dotrze do COMMIT
. Każdy błąd spowoduje przerwanie skryptu i wycofanie.
Użyłem COLUMNPROPERTY
aby sprawdzić istnienie kolumn, możesz zamiast tego użyć dowolnej metody (np. lookup sys.columns
).