Columna de adición de advertencia de pérdida de datos en el medio de una tabla

Se agregó una nueva columna a una tabla, pero la nueva columna no se agregó al final de la definición de la tabla (columna más a la derecha), sino al centro de la tabla.

Diferencias de tabla

Cuando trato de confirmar esto en Redgate SQL Source Control, aparece la advertencia "Estos cambios pueden provocar la pérdida de datos"

  • ¿La pérdida de datos realmente ocurrirá?
  • ¿Hay alguna manera de previsualizar el script de cambio para confirmar que no se perderán datos?
    • ¿Puedo copyr el script y convertirlo fácilmente en un script de Migrations V2?
  • ¿Tendré que hacerlo?
    • Edite la tabla en SSMS y mueva la nueva columna hasta el final
    • o escribir un script de migration?
  • Si es así, ¿hay alguna herramienta útil para hacer las cosas repetitivas?

Divulgación por adelantado de que trabajo para Red Gate en SQL Source Control.

Ese cambio deberá volver a crear una tabla. Por defecto, SSMS no le permitirá save ese cambio. Sin embargo, esa opción debe haberse deshabilitado en SSMS. Está en Herramientas-> Opciones-> Diseñadores-> Diseñadores de tablas y bases de datos-> Evita save cambios que requieren una recreación de tablas.

Dado que la function está deshabilitada, SQL Source Control la ha detectado como una posible situación de pérdida de datos y se le ha preguntado si desea agregar un script de migration.

Si otros desarrolladores de su equipo implementan este cambio a través de un get get, SQL Source Control les informará sobre cualquier posible pérdida de datos con más detalles, según el estado actual de su database local. Si el único cambio es agregar columnas a una tabla existente, esto no soltará los datos en columnas que no se hayan modificado.

Si está implementando en otro DB (p. Ej., Staging / UAT / prod) y tiene SQL Compare, puede usar eso para ver exactamente qué se aplicará a un DB si intenta ejecutarlo en otra database no local. Elija la opción crear script de deployment y podrá verificar el SQL antes de ejecutar.

Como dices, agregar la columna al final de la tabla evitará la necesidad de la reconstrucción, por lo que es probablemente la forma más sencilla de evitar esto si no tienes que preocuparte de dónde está la columna.

Alternativamente, puede agregar un script de migration a:

  1. Crea una nueva tabla con la nueva estructura usando un nombre temporal
  2. Copie los datos existentes a la tabla temporal
  3. Suelta la tabla existente
  4. Cambie el nombre de la nueva tabla temporal al nombre original

Menciona Migrations v2, la característica beta que cambia la forma en que funcionan las migraciones para admitir mejor los sistemas de bifurcación y fusión y DVCS. Ver http://www.networking-gate.com/migrations

Los scripts de migration de la versión 1 necesitarán algunas modificaciones para convertirse en un script de migration v2. Es un cambio bastante trivial. Estamos trabajando para documentar esto en este momento, y comuníquese con nosotros en el Grupo de Google si desea get más información sobre este cambio. https://groups.google.com/forum/#!forum/networking-gate-migrations

Moví la columna al final de la tabla usando SSMS para negar la necesidad de un script de migration.

En un escenario similar, donde no era conveniente mover la columna, esto es lo que hice para convertir un script SSMS a un script Migrations V2.

  • Deshacer el cambio en SSMS (eliminó la columna)
  • Rehacer el cambio en SSMS, pero en lugar de save el cambio directamente en la database, guardé el script de cambio
  • Modificado el script de cambio
    • Recortado el envoltorio de transacción y entorno de SSMS
    • Se agregó una cláusula de guardia: SI COL_LENGTH ('MyTable', 'MyColumn') ES NULL
    • Envolvió el script en BEGIN TRAN – ROLLBACK TRAN para probar el script sin ensuciar la database
    • Reemplazado GO con END BEGIN
    • Probado en una transacción retrotraída
    • Se eliminó la envoltura de desarrollo BEGIN TRAN – ROLLBACK TRAN

Diferencia visual de convertir SSMS a Redgate

Aquí está la consulta SQL simple que ayudará a insert la columna en la tabla de la database sin pérdida de datos.

Digamos que CCDetails es la tabla en la que queremos insert la columna GlobaleNote justo antes de la columna Sys_CreatedBy :

 declare @str1 nvarchar(1000) declare @tableName nvarchar(1000) set @tableName='CCDetails' set @str1 = '' SELECT @str1 = @str1 + ', ' + COLUMN_NAME FROM Information_Schema.Columns WHERE Table_Name = @tableName ORDER BY Ordinal_Position set @str1 = right(@str1, len(@str1) - 2) set @str1 = 'select ' + @str1 +' into '+@tableName+'Temp from '+@tableName+' ; Drop Table '+ @tableName + ' ; EXEC sp_rename '+@tableName+'Temp, '+@tableName set @str1 = REPLACE(@str1,'Sys_CreatedBy','CAST('''' as nvarchar(max)) As GlobaleNote , Sys_CreatedBy' ) exec sp_executesql @str1