sql >> Base de Datos >  >> RDS >> Sqlserver

Agregue una columna a la tabla y luego actualícela dentro de la transacción

GO no es un comando T-SQL. Es un delimitador de lotes. La herramienta del cliente (SSM, sqlcmd, osql, etc.) lo usa para cortar de manera efectiva el archivo en cada GO y enviar al servidor los lotes individuales. Entonces, obviamente, no puede usar GO dentro de IF, ni puede esperar que las variables abarquen el alcance entre lotes.

Además, no puede detectar excepciones sin comprobar el XACT_STATE() para garantizar que la transacción no esté condenada.

El uso de GUID para identificaciones siempre es al menos sospechoso.

Usar restricciones NOT NULL y proporcionar un 'guid' predeterminado como '{00000000-0000-0000-0000-000000000000}' tampoco puede ser correcto.

Actualizado:

  • Separe ALTER y UPDATE en dos lotes.
  • Utilice extensiones sqlcmd para interrumpir el script en caso de error. Esto es compatible con SSMS cuando el modo sqlcmd está activado , sqlcmd, y es trivial admitirlo también en bibliotecas de clientes:dbutilsqlcmd .
  • use XACT_ABORT forzar error para interrumpir el lote. Esto se usa con frecuencia en scripts de mantenimiento (cambios de esquema). Los procedimientos almacenados y los scripts de lógica de aplicación en general usan bloques TRY-CATCH en su lugar, pero con el debido cuidado:Manejo de excepciones y transacciones anidadas .

guión de ejemplo:

: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 un script exitoso alcanzará el COMMIT . Cualquier error anulará la secuencia de comandos y la reversión.

Usé COLUMNPROPERTY para verificar la existencia de columnas, puede usar cualquier método que desee (por ejemplo, buscar sys.columns ).