使用Azure特定功能时在本地运行SQL Server数据库吗?

时间:2019-05-15 16:06:07

标签: sql-server azure azure-sql-database azure-sql-server

我正在考虑使用本地SQL Server将项目迁移到SQL Azure。该数据库具有跨数据库依赖性,其中某些视图引用同一服务器上的另一个数据库,而SQL Azure不支持该数据库。

我已经成功修改了这些表,以使用外部表,这些表使用通过以下方式创建的外部数据源:

CREATE EXTERNAL DATA SOURCE [MyExternalDataSource] WITH
(
    TYPE = RDBMS,
    LOCATION = 'SqlServerName',
    DATABASE_NAME = 'SqlServerDatabaseName',
    CREDENTIAL = cred
);

但是,这种类型的数据源使用的RDBMS类型似乎仅受SQL Azure支持,而不受本地SQL Server支持。针对前者运行此脚本可正常运行,而后者则导致引发以下错误:

  

“ RDBMS”附近的语法不正确

因此,这意味着解决方案中的数据库项目不能同时用于Azure SQL和本地SQL Server安装。

作为一种解决方法,我正在考虑以下选项,尽管每个选项都有其缺点:

  1. 解决方案中有多个数据库项目,其中一个针对SQL Azure,另一个针对SQL Server,尽管这意味着将所有数据库更新都复制到两个项目中。

  2. 从使用外部表转移到Azure提供的数据同步功能,并在两个数据库中重复使用表和数据(消除了使用引起问题的外部数据源的需要)-尽管这样做有一个最少5分钟的延迟(在这种情况下可能可以接受,但肯定不是每个人都可以)

其他开发人员如何处理这种情况,即需要在项目中使用类似SQL Azure的特定功能,但同时还需要能够运行数据库的本地副本以进行开发?

2 个答案:

答案 0 :(得分:0)

您可以尝试创建3个项目:
1.项目仅包含定义为视图的Azure特定引用。
2.项目仅包含定义为视图的SQL Server特定引用。视图的结构应该相同。
3.您的主要项目。在此项目中,您将把以前的一个参考作为“复合项目”参考。
https://docs.microsoft.com/en-us/sql/ssdt/add-database-reference-dialog-box?view=sql-server-2017

答案 1 :(得分:0)

此处概述了几种方法: Conditional logic in PostDeployment.sql script using SQLCMD

尝试所有选项后,最适合我的选项是使用构建事件。

使用此方法,我将项目设置为使用空脚本作为预部署脚本,然后在构建之前将其替换为正确的脚本(内部部署调试和Azure发布)。构建完成后,将在其上复制占位符脚本,以避免将更改后的文件提交给源代码管理。

这是文件夹结构:

Folder structure

在项目文件中,我添加了以下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。