GO is geen T-SQL-opdracht. Is een batchscheidingsteken. De clienttool (SSM, sqlcmd, osql enz.) gebruikt het om effectief te knippen het bestand bij elke GO en stuur de afzonderlijke batches naar de server. Het is dus duidelijk dat je GO niet binnen IF kunt gebruiken, en je kunt ook niet verwachten dat variabelen het bereik over meerdere batches heen zullen spreiden.
U kunt ook geen uitzonderingen opvangen zonder te controleren op de XACT_STATE()
om ervoor te zorgen dat de transactie niet gedoemd is.
Het gebruik van GUID's voor ID's is altijd op zijn minst verdacht.
Het gebruik van NOT NULL-beperkingen en het verstrekken van een standaard 'guid' zoals '{00000000-0000-0000-0000-000000000000}'
kan ook niet correct zijn.
Bijgewerkt:
- Verdeel de ALTER en UPDATE in twee batches.
- Gebruik sqlcmd-extensies om het script bij een fout te breken. Dit wordt ondersteund door SSMS wanneer sqlcmd-modus is ingeschakeld , sqlcmd, en het is triviaal om het ook in clientbibliotheken te ondersteunen:dbutilsqlcmd .
- gebruik
XACT_ABORT
om een fout te forceren om de batch te onderbreken. Dit wordt vaak gebruikt in onderhoudsscripts (schemawijzigingen). Opgeslagen procedures en toepassingslogica-scripts gebruiken in plaats daarvan TRY-CATCH-blokken, maar met de juiste zorg:Afhandeling van uitzonderingen en geneste transacties .
voorbeeldscript:
: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
Alleen een succesvol script bereikt de COMMIT
. Elke fout zal het script afbreken en terugdraaien.
Ik gebruikte COLUMNPROPERTY
om het bestaan van kolommen te controleren, kunt u in plaats daarvan elke gewenste methode gebruiken (bijv. lookup sys.columns
).