运行 从 Azure DevOps 管道比较架构以更新 SQL 数据库项目
Run Schema Compare from Azure DevOps pipeline to update SQL database project
我们有一个 SQL 数据库项目,我们用它来将更改部署到我们的 TEST 和 PROD 环境中。白天开发人员直接在 DEV 数据库上进行更改(不使用数据库项目)。定期在数据库项目中进行架构比较,以收集开发人员在 DEV 数据库中所做的所有更改,以便它们可以通过 Azure 发布管道应用于测试环境。
这在 Azure Pipelines 中运行良好,但我们想要创建一个管道,自动运行 DEV 数据库之间的架构比较并将更改应用到数据库项目(我们必须手动执行此操作)。多年前我调查过这个,命令行不支持将数据库项目作为模式比较的目标。有谁知道现在这种类型的工作流程是否可行?
我同意 Daniel 的观点,运行 应避免直接在 DEV 数据库中更改数据库。您可以尝试使用 sql 脚本作为 this case:
中的示例
set nocount on;
-- Set the two variables newmodel and oldmodel to the appropriate database names and execute the script
declare @newmodel varchar(50), @oldmodel varchar(50);
Set @newmodel = '[NewModel to Compare]';
set @oldmodel = '[OldModel to Compare]';
Declare @Temp table (TABLE_SCHEMA varchar(40), TABLE_NAME varchar(40), COLUMN_NAME varchar(50), ORDINAL_POSITION int, IS_NULLABLE varchar(5), NullChange varchar(5), Comment varchar(50));
Declare @script varchar(5000);
set @script = '
Select nc.TABLE_SCHEMA, nc.TABLE_NAME, nc.COLUMN_NAME, nc.ORDINAL_POSITION, nc.IS_NULLABLE, IIF(nc.IS_NULLABLE <> oc.IS_NULLABLE, ''Yes'', ''No''),
IIF(oc.COLUMN_NAME IS NULL, convert(varchar(20), ''ADDED COLUMN''), convert(varchar(20), ''--'')) as Comment
from {NEW}.INFORMATION_SCHEMA.COLUMNS nc
LEFT join {OLD}.INFORMATION_SCHEMA.COLUMNS oc
on nc.TABLE_NAME = oc.TABLE_NAME and nc.COLUMN_NAME = oc.COLUMN_NAME
UNION ALL
Select oc.TABLE_SCHEMA, oc.TABLE_NAME, oc.COLUMN_NAME, oc.ORDINAL_POSITION, oc.IS_NULLABLE, ''No'', ''DELETED COLUMN'' as Comment
from {OLD}.INFORMATION_SCHEMA.COLUMNS oc
where CONCAT(oc.TABLE_NAME, ''.'', oc.COLUMN_NAME)
not in (Select CONCAT(TABLE_NAME, ''.'', COLUMN_NAME) from {NEW}.INFORMATION_SCHEMA.COLUMNS)
';
Set @script = replace(@script, '{OLD}', @oldmodel);
Set @script = replace(@script, '{NEW}', @newmodel);
--print @script
Insert into @Temp
exec(@script);
Select * from @Temp where Comment <> '--'
order by TABLE_NAME, ORDINAL_POSITION, COLUMN_NAME;
go
正如 Daniel 提到的,在没有数据库项目的情况下使用开发环境不是一个好主意。但是,在某些情况下,由于沙盒价格、测试数据或任何其他限制,我们不得不在公共数据库中工作。在这种情况下,检查 DEV 数据库何时准备好同步更改太复杂了,因为它可能包含原始更改。考虑使用以下流程:您的开发人员将更改添加到源代码管理下的数据库项目。他们可以直接更改 DEV 数据库,但每个开发人员只将其工作范围提交给源代码管理。在这种情况下,您可以在源代码管理中查看每个用户故事和错误的更改,并在需要时 link 将它们添加到相应的工作项中。此外,您可以添加一个集成数据库来检查新更改的一致性:
DEV (manually + commit to SC)
-> INT (pipelines CI/CD)
-> TEST
-> PROD
作为额外的想法:
- 您可以尝试创建一个编码 UI 测试或 Selenim 测试来按下 VS 上的按钮并更新您的数据库项目。然后你可以将它添加到管道并每晚更新你的 SC。
SqlPackage.exe
生成更新脚本 Database
->DacPac file
。但是,没有办法将其应用到数据库项目中。
我们有一个 SQL 数据库项目,我们用它来将更改部署到我们的 TEST 和 PROD 环境中。白天开发人员直接在 DEV 数据库上进行更改(不使用数据库项目)。定期在数据库项目中进行架构比较,以收集开发人员在 DEV 数据库中所做的所有更改,以便它们可以通过 Azure 发布管道应用于测试环境。
这在 Azure Pipelines 中运行良好,但我们想要创建一个管道,自动运行 DEV 数据库之间的架构比较并将更改应用到数据库项目(我们必须手动执行此操作)。多年前我调查过这个,命令行不支持将数据库项目作为模式比较的目标。有谁知道现在这种类型的工作流程是否可行?
我同意 Daniel 的观点,运行 应避免直接在 DEV 数据库中更改数据库。您可以尝试使用 sql 脚本作为 this case:
中的示例set nocount on;
-- Set the two variables newmodel and oldmodel to the appropriate database names and execute the script
declare @newmodel varchar(50), @oldmodel varchar(50);
Set @newmodel = '[NewModel to Compare]';
set @oldmodel = '[OldModel to Compare]';
Declare @Temp table (TABLE_SCHEMA varchar(40), TABLE_NAME varchar(40), COLUMN_NAME varchar(50), ORDINAL_POSITION int, IS_NULLABLE varchar(5), NullChange varchar(5), Comment varchar(50));
Declare @script varchar(5000);
set @script = '
Select nc.TABLE_SCHEMA, nc.TABLE_NAME, nc.COLUMN_NAME, nc.ORDINAL_POSITION, nc.IS_NULLABLE, IIF(nc.IS_NULLABLE <> oc.IS_NULLABLE, ''Yes'', ''No''),
IIF(oc.COLUMN_NAME IS NULL, convert(varchar(20), ''ADDED COLUMN''), convert(varchar(20), ''--'')) as Comment
from {NEW}.INFORMATION_SCHEMA.COLUMNS nc
LEFT join {OLD}.INFORMATION_SCHEMA.COLUMNS oc
on nc.TABLE_NAME = oc.TABLE_NAME and nc.COLUMN_NAME = oc.COLUMN_NAME
UNION ALL
Select oc.TABLE_SCHEMA, oc.TABLE_NAME, oc.COLUMN_NAME, oc.ORDINAL_POSITION, oc.IS_NULLABLE, ''No'', ''DELETED COLUMN'' as Comment
from {OLD}.INFORMATION_SCHEMA.COLUMNS oc
where CONCAT(oc.TABLE_NAME, ''.'', oc.COLUMN_NAME)
not in (Select CONCAT(TABLE_NAME, ''.'', COLUMN_NAME) from {NEW}.INFORMATION_SCHEMA.COLUMNS)
';
Set @script = replace(@script, '{OLD}', @oldmodel);
Set @script = replace(@script, '{NEW}', @newmodel);
--print @script
Insert into @Temp
exec(@script);
Select * from @Temp where Comment <> '--'
order by TABLE_NAME, ORDINAL_POSITION, COLUMN_NAME;
go
正如 Daniel 提到的,在没有数据库项目的情况下使用开发环境不是一个好主意。但是,在某些情况下,由于沙盒价格、测试数据或任何其他限制,我们不得不在公共数据库中工作。在这种情况下,检查 DEV 数据库何时准备好同步更改太复杂了,因为它可能包含原始更改。考虑使用以下流程:您的开发人员将更改添加到源代码管理下的数据库项目。他们可以直接更改 DEV 数据库,但每个开发人员只将其工作范围提交给源代码管理。在这种情况下,您可以在源代码管理中查看每个用户故事和错误的更改,并在需要时 link 将它们添加到相应的工作项中。此外,您可以添加一个集成数据库来检查新更改的一致性:
DEV (manually + commit to SC)
-> INT (pipelines CI/CD)
-> TEST
-> PROD
作为额外的想法:
- 您可以尝试创建一个编码 UI 测试或 Selenim 测试来按下 VS 上的按钮并更新您的数据库项目。然后你可以将它添加到管道并每晚更新你的 SC。
SqlPackage.exe
生成更新脚本Database
->DacPac file
。但是,没有办法将其应用到数据库项目中。