GO non è un comando T-SQL. È un delimitatore batch. Lo strumento client (SSM, sqlcmd, osql ecc.) lo utilizza per tagliare in modo efficace il file ad ogni GO e inviare al server i singoli batch. Quindi ovviamente non puoi usare GO all'interno di IF, né puoi aspettarti che le variabili coprano l'ambito tra i batch.
Inoltre, non è possibile rilevare le eccezioni senza controllare XACT_STATE()
per garantire che la transazione non sia condannata.
L'uso dei GUID per gli ID è sempre almeno sospetto.
Utilizzo di vincoli NOT NULL e fornitura di un "guid" predefinito come '{00000000-0000-0000-0000-000000000000}'
inoltre non può essere corretto.
Aggiornato:
- Separare ALTER e UPDATE in due batch.
- Utilizzare le estensioni sqlcmd per interrompere lo script in caso di errore. Ciò è supportato da SSMS quando la modalità sqlcmd è attiva , sqlcmd ed è banale supportarlo anche nelle librerie client:dbutilsqlcmd .
- usa
XACT_ABORT
per forzare l'errore per interrompere il batch. Viene spesso utilizzato negli script di manutenzione (modifiche dello schema). Le stored procedure e gli script logici dell'applicazione in generale utilizzano invece i blocchi TRY-CATCH, ma con la dovuta attenzione:Gestione delle eccezioni e transazioni nidificate .
script di esempio:
: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
Solo uno script riuscito raggiungerà il COMMIT
. Qualsiasi errore interromperà lo script e il rollback.
Ho usato COLUMNPROPERTY
per verificare l'esistenza delle colonne, puoi invece utilizzare qualsiasi metodo che preferisci (ad es. ricerca sys.columns
).