数据库更改版本控制

时间:2016-10-08 22:00:09

标签: database msbuild sql-server-data-tools

我的问题是我找不到如何从命令行更新sqlproj以跟踪存储库中的数据库更改的方法。根据{{​​3}}:“此版本中没有直接支持的项目”,但是尝试了下一个命令但没有成功:

msbuild PathToMyProject.sqlproj /t:SqlSchemaCompare /p:SqlScmpFilePath=SomePath/ComparationConfiguration.scmp /p:target=PathToMyProject.sqlproj /p:Deploy="true"

并无法找到如何做到这一点的方法。有可能吗?
从另一方面看,我可以将数据库模式与dacpac文件(sqlproj的编译输出)进行比较,以获得数据库项目中不存在的更改,但是为了自动化数据库更改跟踪它看起来没用,因为每次我得到一些更改我需要手动打开相关解决方案,进行比较,更新目标数据库项目,然后检查对存储库的更改

2 个答案:

答案 0 :(得分:2)

没有命令行支持从数据库自动更新数据库项目。这主要是因为SSDT要启用的工作流程是脱机数据库开发:期望首先对数据库项目进行更改,然后将其发布到数据库。

答案 1 :(得分:0)

正如@Steven Green在另一个答案所说的那样,目前无法从命令行使用SSDT更新数据库项目(希望它很快就会推出),但是已经找到了另一种版本数据库模式更改的方法数据库项目(如果将添加任何更新它的命令行方法,则将其留待将来使用)。解决方案基于C#程序,该程序使用SMO生成数据库模式创建sql脚本。因此,我们只是将此脚本存储在存储库中,并使用运行检查的CI服务器配置每天更新,以防发现任何更改 - 将它们提交到存储库。将这些步骤留给遇到同样问题的人:

  1. 需要参考下一个依赖项(我的位于 C:\ Program Files(x86)\ Microsoft SQL Server \ 130 \ 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);
                    }
                }
            }
        }
    }