数据库更改版本控制

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 服务器配置每天更新,以防发现任何更改 - 将它们提交到存储库中。将这些步骤留给遇到同样问题的人:

  1. 需要参考下一个依赖项(我的位于 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
  2. 使用下一个代码生成文件:

    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);
                    }
                }
            }
        }
    }