数据丢失警告在表中间添加列

时间:2013-10-11 08:32:32

标签: sql-server version-control redgate

新表已添加到表中,但新列未添加到表定义的末尾(最右边的列),而是添加到表的中间。

Table differences

当我尝试在Redgate SQL Source Control中提交时,我收到警告“这些更改可能会导致数据丢失”

  • 数据丢失真的会发生吗?
  • 有没有办法预览更改脚本以确认没有数据丢失?
    • 我可以复制脚本并轻松将其转换为Migrations V2脚本吗?
  • 我必须这样做
    • 在SSMS中编辑表格并将新列移至末尾
    • 或编写迁移脚本?
  • 如果是这样,有没有方便的工具来做重复的事情?

3 个答案:

答案 0 :(得分:4)

我在SQL Source Control上为Red Gate工作的前期披露。

该更改需要重新创建一个表。默认情况下,SSMS不允许您保存该更改。但是,必须在SSMS中禁用该选项。它位于工具 - >选项 - >设计器 - >表和数据库设计器 - >防止保存需要重新创建表的更改。

鉴于该功能已被禁用,SQL Source Control随后将其选为潜在的数据丢失情况,并提示您是否要添加迁移脚本。

如果团队中的其他开发人员通过获取最新信息来提取此更改,则SQL源代码管理将根据其本地数据库的当前状态,让他们了解任何可能的数据丢失和更多详细信息。如果唯一的更改是将列添加到现有表中,则不会将数据放在未更改的列中。

如果要部署到另一个数据库(例如staging / UAT / prod)并且有SQL Compare,那么如果尝试对另一个非本地数据库运行此命令,则可以使用它来确切地查看将应用于数据库的内容。选择create deployment script选项,您可以在运行之前检查SQL。

正如您所说,将列添加到表的末尾将避免重建的需要,因此如果您不需要担心列的位置,这可能是避免这种情况的最简单方法。

或者,您可以将迁移脚本添加到:

  1. 使用临时名称
  2. 创建一个包含新结构的新表
  3. 将现有数据复制到临时表
  4. 删除现有表格
  5. 将新临时表重命名为原始名称
  6. 您提到了迁移v2,这是一项测试版功能,用于更改迁移的工作方式,以便更好地支持分支和合并以及DVCS系统。见http://www.red-gate.com/migrations

    版本1迁移脚本需要进行一些修改才能转换为v2迁移脚本。这是一个相当微不足道的变化。我们目前正在努力记录这一情况,如果您想了解有关此更改的更多信息,请与Google小组联系。 https://groups.google.com/forum/#!forum/red-gate-migrations

答案 1 :(得分:1)

我使用SSMS将列移动到表的末尾,以消除对迁移脚本的需求。

在类似的情况下,移动列不方便,这就是我将SSMS脚本转换为Migrations V2脚本所做的。

  • 撤消SSMS中的更改(删除列)
  • 重做SSMS中的更改,但不是将更改直接保存到数据库,而是保存了更改脚本
  • 修改了更改脚本
    • 修剪SSMS交易&环境包装
    • 添加了一个保护条款:IF COL_LENGTH('MyTable','MyColumn')IS NULL
    • 在BEGIN TRAN - ROLLBACK TRAN中包装脚本以测试脚本而不会弄脏数据库
    • 用END BEGIN取代GO
    • 在回滚交易中测试
    • 删除了BEGIN TRAN - ROLLBACK TRAN开发包装器

Visual diff of converting SSMS to Redgate

答案 2 :(得分:0)

这是一个简单的sql查询,它有助于在数据库表中插入列而不会丢失数据。

让我们说CCDetails是我们要在列GlobaleNote之前插入列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