如何在部署SQL SSDT项目时跟踪数据更改

时间:2017-12-01 22:35:03

标签: sql visual-studio-2015 sql-server-data-tools database-project

我们使用SSDT DACPAC部署升级数据库。开发人员在VisualStudio 2015中处理项目,并根据需要修改架构。

开发人员还将Pre和Post部署脚本添加到项目中。其中一些脚本可确保某些表始终包含预期数据。其他人在平台升级过程中添加,移动或改变数据。

我们需要改进数据库部署期间生成的输出,以便在部署之后,我们有一个人类可读的列表,其中包含在部署过程中发生更改的任何data

我目前正在考虑两种方法。但似乎都不理想。他们是:

  

1)手动将日志记录添加到项目中的所有Pre和Post脚本。这当然是一种选择。但它并不理想,因为它使升级脚本变得复杂,并且有时可能会被开发人员遗漏或错误地完成。由于目标是检测作为部署的一部分而发生的意外数据更改,因此这种不确定性真的很糟糕。通用解决方案更可取。

     

2)这是我对通用解决方案的最佳尝试:作为部署过程的一部分,为数据库中的所有用户表启用SQL Change Data Capture。然后,在部署结束时,收集所有捕获的更改并禁用CDC。我实际上有这个工作。但是,在数据库中的所有表上启用CDC的过程需要几分钟(我们的一个数据库有775个表,在所有这些表上启用CDC大约需要3分钟)。这种方法也感觉非常沉重?

我的问题是。有没有更好的方法来实现我可靠地生成作为数据库部署的一部分而更改的数据报告的目标,因为部署运行任意的Pre和Post部署脚本?

如果似乎没有更好的方法,我会很感激对选项#2的反馈。考虑到这个,我疯了吗?

1 个答案:

答案 0 :(得分:0)

<块引用>

其中一些脚本确保某些表中始终包含预期的数据

首先,未验证 PreDeploy/PostDeploy 脚本。我更喜欢将它们仅用作启动点,并在存储过程中进行实际工作。

所以不要写:

INSERT INTO dbo.tab1(id, col1, col2) VALUES (...,..., ...); 

并将其插入到 PostDeployscript 中,您可以输入:

EXEC dbo.Populate_Tab1;

并将存储过程定义为:

CREATE PROCEDURE dbo.Populate_Tab1
AS
BEGIN
   -- idempotent script, here by using MERGE
   WITH src(id, col1, col2,...) AS (
       SELECT 1, ..., ...  UNION ALL
       SELECT ...
   )
   MERGE dbo.tab1 trg
   USING src
     ON trg.id = src.id
   WHEN MATCHED THEN UPDATE
    ...
   WHEN NOT MATCHED BY SOURCE THEN DELETE
   WHEN NOT MATCHED BY TARGET THEN INSERT
     ...

END

关键点:存储过程必须是idempotent

通过这种方式,您始终可以确保该表包含所需的输入数据,并且存储过程已经过验证。


Kamil Nowinski 描述了类似的方法:

<块引用>

Script and deploy the data for database from SSDT project

优点:

存储过程是数据库项目的一部分。

它们将被验证和编译,从而避免不受控制的代码的潜在错误

对 SP 的更改仅在某些内容发生更改时才会出现在输出脚本中。

在运行前检查脚本更容易,因为它不包含不必要的代码

在部署后脚本中——只有一行代码永远不会改变。