Fet*_*che 7 sql-server database-project sql-server-data-tools
在SQL Server数据工具中,您可以使用部署选项"如果可能发生数据丢失则阻止增量部署",我认为这是保持检查的最佳做法.
假设我们有一个表foo,一个现在是冗余的列栏 - 没有依赖项,外键等等,我们已经在数据层和存储过程中删除了对该列的引用,因为它根本就没用过.换句话说,我们对放弃此列不会产生任何不利影响感到满意.
美中不足有几种苍蝇:
在填充列时,除非我们更改"阻止增量部署,否则可能发生数据丢失"选项,否则发布将失败.这个选项是在数据库级别,而不是表级,因此由于客户端的分布式特性,我们必须在所有数据库更新之前关闭"数据丢失"选项数月,并将其重新打开一旦所有客户都更新了(我们的数据库有我们构建的版本号).
您可能认为我们可以使用预部署脚本解决此问题,例如
if exists (select * from information_schema.columns where table_name = 'foo' and column_name = 'bar') BEGIN
alter table foo drop constraint DF_foo_bar
alter table foo drop column bar
END
Run Code Online (Sandbox Code Playgroud)
但是,除非我们关闭"数据丢失可能发生"选项,否则这将失败.
我只是对其他人在这种情况下做了什么感兴趣,因为我想要具有目前看来不可能的粒度.
由于 SSDT 的操作顺序,预部署脚本无法按照您希望的方式工作:
因此,当然,模式差异被识别为 #2 的一部分,并生成适当的 SQL 来删除该列(包括阻止数据丢失的检查),然后您的手动预部署脚本可以“删除它”。
如果您查看后台生成的脚本以检测(并因此阻止)可能的数据丢失,它会通过运行以下内容来检查是否有任何行:
IF EXISTS (select top 1 1 from [dbo].[Table]) RAISERROR ('Rows were detected. The schema update is terminating because data loss might occur.', 16, 127)
Run Code Online (Sandbox Code Playgroud)
这意味着行的简单存在将阻止列被删除。除了使用基于版本号的条件部署步骤在 SSDT 部署之外(和之前)手动处理问题之外,我们还没有找到任何解决此问题的方法。
您提到分布式客户端,这意味着您拥有某种自动发布/更新机制。您还提到版本号作为数据库的一部分 - 您能否在部署中包含手动 SQL 脚本(在 sqlpackage.exe 命令之前,我假设您正在运行)?这与我们所做的类似(我们的工作是在 Powershell 中,但您明白要点了):
IF VersionNumber < 2.8
BEGIN
ALTER TABLE X DROP COLUMN Y
END
Run Code Online (Sandbox Code Playgroud)
免责声明:这个 SQL 绝不是有效的,它只是暗示一个想法的伪代码!
所以我通过以下步骤完成了这项任务:
1)因为我们要创建表#Foo,所以确保在向前移动之前删除该表(如果存在).
2)在预部署脚本中:如果列存在,则创建一个临时表#Foo并从Foo中选择所有行到#Foo.
3)从#Foo中删除列
4)删除Foo中的所有行(现在没有数据丢失,因为没有数据)
5)在部署后脚本中:如果#Foo存在,则从#Foo中选择所有行到Foo
6)删除表#Foo
和代码:
预部署脚本
if(Object_ID('TempDB..#Foo') is not null)
begin
drop table #Foo
end
if exists (
select *
from sys.columns
where Name = 'Bar'
and Object_ID = Object_ID('Foo')
)
begin
select * into #Foo
from Foo
alter table #Foo drop column Bar
-- Now that we've made a complete backup of Foo, we can delete all its data
delete Foo
end
Run Code Online (Sandbox Code Playgroud)
部署后脚本
if(Object_ID('TempDB..#Foo') is not null)
begin
insert into Foo
select * from #Foo
drop table #Foo
end
Run Code Online (Sandbox Code Playgroud)
警告:根据您的环境,依赖于版本而不是条件中的列和临时表可能更明智
| 归档时间: |
|
| 查看次数: |
2787 次 |
| 最近记录: |