Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Aggiungi colonna alla tabella e quindi aggiornala all'interno della transazione

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 ).