1

我在 SQL-Server 2012 上使用带有 TFS 的 Visual Studio 2013。具体来说,我在 VS 中使用 SQL-Server Data Tools 进行 SQL 开发,而不是在 SQL-Server Management Studio 中使用。

简而言之,SQLPackage 似乎不执行 Post-Deployment SQL 脚本。

具体情况是:我有一个 VS SQL 数据库项目“ADMIR”,它在过去几周一直在开发,并且在 SQL 和它的部署方面逐渐变得更加复杂。该数据库包括一些动态生成的表,因此我引入了 SQL 命令变量来引用两个数据库(一个是实际的 ADMIR 数据库,另一个是同一服务器上的数据库)。因此,我为这两个数据库添加了对 dacpacs 的数据库引用。

ADMIR 项目将构建良好。

还有一个 Post-Deployment SQL 脚本,在引入 SQL 命令变量之前,它也可以正常运行并初始化各种表数据。

但是,我的理解是 SQL 命令变量不适用于 VS/TFS 发布操作,因为不再执行部署后脚本。

没关系,因为最终我想编写脚本/自动化 ADMIR 项目的发布/部署,所以我已经转向使用 SQLPackage 来执行发布。

同样,这似乎工作正常 - My SQL Package 批处理命令将执行并记录错误/输出(如适用)并将我的 Build dacpac 成功发布到目标服务器。但是,它似乎完全忽略了部署后脚本。此外,输出报告未设置 SQL 命令变量。

这些是各种脚本和配置设置:

SQLPackage 批处理命令:

::Publish the ADMIR database using the ADMIR.DEV.Publish.xml Profile.
"C:\Program Files (x86)\Microsoft SQL Server\120\DAC\bin\SqlPackage.exe" 
    /Action:Publish 
    /Profile:"C:\Source Control\ADMIR\ReleaseControl\ADMIR.DEV.publish.xml"
    /SourceFile:"C:\Source Control\ADMIR\Build\ADMIR.dacpac"
    2> "C:\Source Control\ADMIR\ReleaseControl\Publish_Error.txt" 
    > "C:\Source Control\ADMIR\ReleaseControl\Publish_Output.txt"

ADMIR.DEV.publish.xml 发布配置文件:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <IncludeCompositeObjects>True</IncludeCompositeObjects>
    <TargetDatabaseName>ADMIR</TargetDatabaseName>
    <DeployScriptFileName>ADMIR.sql</DeployScriptFileName>
    <TargetConnectionString>Data Source=FOOBAR;Integrated Security=True;Pooling=False</TargetConnectionString>
    <ProfileVersionNumber>1</ProfileVersionNumber>
  </PropertyGroup>
  <ItemGroup>
    <SqlCmdVariable Include="ADMIRDatabaseName">
      <Value>ADMIR</Value>
    </SqlCmdVariable>
    <SqlCmdVariable Include="XYZDatabaseName">
      <Value>XYZDEV</Value>
    </SqlCmdVariable>
  </ItemGroup>
</Project>

Script.PostDeploy.sql(前几行):

/* ADMIR Post-Deployment Script Template */
PRINT N'Post Deploy Script started:'+CAST(GETDATE() AS NVARCHAR(20))+N'.'
PRINT N'SQLCMD Variable $ADMIRDBName:'+[$(ADMIRDatabaseName)]+N'.'
PRINT N'SQLCMD Variable $XYZDBName:'+[$(XYZDatabaseName)]+N'.'

/* Purge existing data as we'll repopulate with what is required for a fresh deploy */
PRINT N'Purging existing table data...'
DELETE FROM [ADMIR].[Engine].[ProcessingStatus]
DELETE FROM [ADMIR].[Engine].[DataField]
DELETE FROM [ADMIR].[Engine].[DataKeyField]
...
...

运行构建时,我可以看到 ADMIR_Create.sql 脚本确实包含所有 Post-Deploy 语句。即我可以在这个文件中看到上面的代码行。

** ADMIR.sqlproj 文件包含部署后脚本和 SQL 命令变量:**

<ItemGroup>
    ...
    ...
    <PostDeploy Include="ReleaseControl\Script.PostDeploy.sql" />
</ItemGroup>
...
...
<ItemGroup>
<SqlCmdVariable Include="ADMIRDatabaseName">
  <DefaultValue>ADMIR</DefaultValue>
  <Value>$(SqlCmdVar__7)</Value>
</SqlCmdVariable>
<SqlCmdVariable Include="XYZDatabaseName">
  <DefaultValue>XYZDEV</DefaultValue>
  <Value>$(SqlCmdVar__6)</Value>
</SqlCmdVariable>

发布日志,Publish_Output.txt:

Publishing to database 'ADMIR' on server 'FOOBAR'.
Initializing deployment (Start)
*** The following SqlCmd variables are not defined in the target scripts: ADMIRDatabaseName XYZDatabaseName.
Initializing deployment (Complete)
Analyzing deployment plan (Start)
Analyzing deployment plan (Complete)
Updating database (Start)
Update complete.
Updating database (Complete)
Successfully published database.

所以:

  1. 为什么没有执行部署后脚本?我没有看到任何与之相关的日志记录信息。

  2. 为什么 SQLPackage 输出日志指出 SQL 命令变量未定义,当它们在发布配置文件中时?

  3. 可能与 2 相关。.sqlproj 文件是否正确将 SQL 命令变量的值作为变量本身,例如 $(SqlCmdVar__7)?__6 和 __7 来自哪里?

感谢您的帮助!

4

2 回答 2

1

我发现在 Visual Studio 2017 中创建的新 .sqlproj 文件不包含“默认”Predeployment.sqlPostDeployment.sql文件,因此我手动添加了一个。

发布未执行,PostDeployment.sql因为文件Build Action设置为None. 更改Build ActionPostDeploy解决问题。

在此处输入图像描述

于 2018-09-08T19:53:20.653 回答
0

根据我的评论,登录 MSDN Connect 的问题似乎是原因。即与数据库的 dacpac 同名的 SQLCMD 变量导致脚本不被执行。当我删除此引用并将相关的 SQLCMD 变量更改为 DB 名称的文字值时,项目将构建并根据需要执行部署后脚本。

于 2016-02-16T15:09:32.673 回答