这里概述了几种方法:
Conditional logic in PostDeployment.sql script using SQLCMD
在尝试了所有选项后,对我有用的是使用构建事件。
使用此方法,我将项目设置为使用空脚本作为预部署脚本,然后在构建之前将其替换为正确的脚本(本地部署调试和 Azure 发布)。构建后,占位符脚本会被复制回它,以避免将更改的文件提交到源代码管理。
这是文件夹结构:
在项目文件中,我添加了以下 BeforeBuild 和 AfterBuild 目标:
<Target Name="BeforeBuild">
<Copy Condition=" '$(Configuration)' == 'Debug' " SourceFiles="Pre-Deployment\OnPremises.PreDeploymentScript.sql" DestinationFiles="Pre-Deployment\PreDeploymentScript.sql" OverwriteReadOnlyFiles="true" />
<Copy Condition=" '$(Configuration)' == 'Release' " SourceFiles="Pre-Deployment\Azure.PreDeploymentScript.sql" DestinationFiles="Pre-Deployment\PreDeploymentScript.sql" OverwriteReadOnlyFiles="true" />
</Target>
<Target Name="AfterBuild">
<Copy SourceFiles="Pre-Deployment\Empty.PreDeploymentScript.sql" DestinationFiles="Pre-Deployment\PreDeploymentScript.sql" OverwriteReadOnlyFiles="true" />
</Target>
Azure 预部署脚本创建外部数据源(在单独的脚本中,此处未显示)和外部表:
IF (NOT EXISTS(SELECT * FROM sys.tables WHERE NAME = 'MyExternalTable' AND is_external = 1))
BEGIN
PRINT 'Creating external table: MyExternalTable'
CREATE EXTERNAL TABLE [MySchema].[MyExternalTable](
[Id] [int],
[Name] [nvarchar](3000) NOT NULL
)
WITH
(
DATA_SOURCE = [ExternalDataSourceName]
);
PRINT 'Created external table: MyExternalTable'
END
ELSE
BEGIN
PRINT 'External table ''MyExternalTable'' is already created'
END
GO
虽然本地只是创建一些同义词:
IF NOT EXISTS(SELECT * FROM sys.synonyms WHERE name = 'MyExternalTable')
BEGIN
CREATE SYNONYM [MySchema].[MyExternalTable] FOR [OtherDb].[OtherSchema].[OtherTable]
END
然后视图可以无缝地使用它,而不必知道它们是使用外部数据源从外部表中获取数据,还是使用同义词引用同一服务器上的另一个数据库:
CREATE VIEW [dbo].[MyView] AS SELECT * FROM [Myschema].[MyTable]
虽然感觉有点笨拙,但它似乎运行良好,并且允许使用单个数据库项目部署到 Azure 和本地(本地)SQL Server。