GO не е T-SQL команда. Е пакетен разделител. Клиентският инструмент (SSM, sqlcmd, osql и т.н.) го използва за ефективно изрязване файла на всеки GO и изпращане на сървъра на отделните партиди. Така че очевидно не можете да използвате GO вътре в IF, нито можете да очаквате променливите да обхващат обхват в партиди.
Освен това не можете да уловите изключения, без да проверите за XACT_STATE()код>
за да се гарантира, че транзакцията не е обречена.
Използването на GUID за ID винаги е най-малкото подозрително.
Използване на ограничения NOT NULL и предоставяне на „guid“ по подразбиране като '{00000000-0000-0000-0000-000000000000}'
също не може да бъде правилно.
Актуализирано:
- Разделете ALTER и UPDATE на две групи.
- Използвайте разширения sqlcmd, за да прекъснете скрипта при грешка. Това се поддържа от SSMS, когато режимът sqlcmd е включен , sqlcmd и е тривиално да се поддържа и в клиентски библиотеки:dbutilsqlcmd .
- използвайте
XACT_ABORT
за принудителна грешка за прекъсване на партидата. Това често се използва в скриптове за поддръжка (промени в схемата). Съхранените процедури и логическите скриптове на приложения като цяло използват TRY-CATCH блокове вместо това, но с подходяща грижа:Обработка на изключения и вложени транзакции .
примерен скрипт:
: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
Само успешен скрипт ще достигне до COMMIT
. Всяка грешка ще прекъсне скрипта и ще върне назад.
Използвах COLUMNPROPERTY
за да проверите за съществуване на колона, можете да използвате всеки метод, който желаете вместо това (напр. търсене sys.columns
).