数据库更改版本控制
Database changes versioning
我的问题是我找不到如何从命令行更新 sqlproj 以跟踪存储库中的数据库更改的方法。根据 this post:"Projects not directly supported in this release",但是尝试了下一个命令但没有成功:
msbuild PathToMyProject.sqlproj /t:SqlSchemaCompare /p:SqlScmpFilePath=SomePath/ComparationConfiguration.scmp /p:target=PathToMyProject.sqlproj /p:Deploy="true"
并且找不到执行此操作的方法。有可能吗?
从另一方面看,我可以将数据库架构与 dacpac 文件(sqlproj 的编译输出)进行比较,以获取数据库项目中不存在的更改,但是对于数据库更改跟踪的自动化,它看起来毫无用处,因为每次我得到一些更改我需要手动打开相关解决方案,进行比较,更新目标数据库项目,然后检查存储库的变化
不支持从数据库自动更新数据库项目的命令行。这主要是因为 SSDT 旨在启用的工作流是离线数据库开发:期望首先对数据库项目进行更改,然后发布到数据库。
正如 at another answer there are no way currently to update database project using SSDT from command-line(hope it will be available soon), however have found another way to version database schema changes without database project(have left it for future in case any command-line method to update it would be added). Solution is based on C# program that generates database schema creation sql script using SMO 所说。因此,我们只是将此脚本存储在存储库中,并使用运行检查的 CI 服务器配置每天更新,以防发现任何更改 - 将它们提交到存储库中。将这些步骤留给遇到同样问题的人:
需要参考下一个依赖项(我的位于
C:\Program Files (x86)\Microsoft SQL Server0\SDK\Assemblies):
- Microsoft.SqlServer.ConnectionInfo.dll
- Microsoft.SqlServer.Management.Sdk.Sfc.dll
- Microsoft.SqlServer.Smo.dll
- Microsoft.SqlServer.SmoExtended.dll
使用下一个代码生成文件:
using System;
using System.Configuration;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
namespace ScriptGenerator {
class Program {
private static string GetTransferScript(Database database){
var transfer = new Transfer(database) {
CopyAllObjects = true,
CopyAllSynonyms = true,
CopyData = false,
PreserveDbo = true,
Options = {
WithDependencies = true,
DriAll = true,
Triggers = true,
Indexes = true,
SchemaQualifyForeignKeysReferences = true,
ExtendedProperties = true,
IncludeDatabaseRoleMemberships = true,
Permissions = true
}
};
var transferScript = new StringBuilder();
foreach (var scriptLine in transfer.ScriptTransfer()) {
transferScript.AppendLine(scriptLine);
}
return transferScript.ToString();
}
static void Main(string[] args){
var databaseName = "yourDataseName";
var outputSqlFile = Path.GetFullPath($"DatabaseSchemaScript.sql");
if (File.Exists(outputSqlFile))
File.Delete(outputSqlFile);
using (var connection = new SqlConnection(ConfigurationManager.AppSettings["DatabaseConnectionString"])) {
var server = new Server(new ServerConnection(connection));
if (!server.Databases.Contains(databaseName))
throw new Exception($"Database '{databaseName}' does not exists on server{connection.DataSource}");
var database = server.Databases[databaseName];
var transferScript = GetTransferScript(database);
using (var sw = new StreamWriter(outputSqlFile)) {
sw.WriteLine(transferScript);
}
}
}
}
}
我的问题是我找不到如何从命令行更新 sqlproj 以跟踪存储库中的数据库更改的方法。根据 this post:"Projects not directly supported in this release",但是尝试了下一个命令但没有成功:
msbuild PathToMyProject.sqlproj /t:SqlSchemaCompare /p:SqlScmpFilePath=SomePath/ComparationConfiguration.scmp /p:target=PathToMyProject.sqlproj /p:Deploy="true"
并且找不到执行此操作的方法。有可能吗?
从另一方面看,我可以将数据库架构与 dacpac 文件(sqlproj 的编译输出)进行比较,以获取数据库项目中不存在的更改,但是对于数据库更改跟踪的自动化,它看起来毫无用处,因为每次我得到一些更改我需要手动打开相关解决方案,进行比较,更新目标数据库项目,然后检查存储库的变化
不支持从数据库自动更新数据库项目的命令行。这主要是因为 SSDT 旨在启用的工作流是离线数据库开发:期望首先对数据库项目进行更改,然后发布到数据库。
正如
需要参考下一个依赖项(我的位于 C:\Program Files (x86)\Microsoft SQL Server0\SDK\Assemblies):
- Microsoft.SqlServer.ConnectionInfo.dll
- Microsoft.SqlServer.Management.Sdk.Sfc.dll
- Microsoft.SqlServer.Smo.dll
- Microsoft.SqlServer.SmoExtended.dll
使用下一个代码生成文件:
using System; using System.Configuration; using System.Data.SqlClient; using System.IO; using System.Text; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Smo; namespace ScriptGenerator { class Program { private static string GetTransferScript(Database database){ var transfer = new Transfer(database) { CopyAllObjects = true, CopyAllSynonyms = true, CopyData = false, PreserveDbo = true, Options = { WithDependencies = true, DriAll = true, Triggers = true, Indexes = true, SchemaQualifyForeignKeysReferences = true, ExtendedProperties = true, IncludeDatabaseRoleMemberships = true, Permissions = true } }; var transferScript = new StringBuilder(); foreach (var scriptLine in transfer.ScriptTransfer()) { transferScript.AppendLine(scriptLine); } return transferScript.ToString(); } static void Main(string[] args){ var databaseName = "yourDataseName"; var outputSqlFile = Path.GetFullPath($"DatabaseSchemaScript.sql"); if (File.Exists(outputSqlFile)) File.Delete(outputSqlFile); using (var connection = new SqlConnection(ConfigurationManager.AppSettings["DatabaseConnectionString"])) { var server = new Server(new ServerConnection(connection)); if (!server.Databases.Contains(databaseName)) throw new Exception($"Database '{databaseName}' does not exists on server{connection.DataSource}"); var database = server.Databases[databaseName]; var transferScript = GetTransferScript(database); using (var sw = new StreamWriter(outputSqlFile)) { sw.WriteLine(transferScript); } } } } }