SQL Server Express equivalent for EXTERNAL DATA SOURCE

不打扰是莪最后的温柔 提交于 2019-12-25 05:13:13

问题


As per https://azure.microsoft.com/en-us/documentation/articles/sql-database-elastic-query-getting-started-vertical/, it is now possible for one database in Azure SQL to query other Azure SQL databases. For my use case, I plan to have one database serving reference data for other databases, which fits nicely to Topology 1 (vertical sharding).

This is great for a deployed environment, but for local development I typically develop using SQL Server Express. As of SQL Server 2012 Express, the CREATE EXTERNAL DATA SOURCE is not a valid syntax.

Is it possible to also reap the benefit of external data source for local development?


回答1:


After weighing the feature sets, I decided to differentiate the setup of my local database and Azure SQL.

  • When local SQL Server database wants to reference an Azure SQL database, it can do so using Linked Server
  • When a fellow Azure SQL database wants to reference another Azure SQL database, only then it uses external data source

i.e. locally

-- Make a link to the cloud
EXEC sp_addlinkedserver   
   @server=N'MyExternalServer', 
   @srvproduct=N'Azure SQL Db',
   @provider=N'SQLNCLI', 
   @datasrc=N'<server address>',
   @catalog='<database name>';
GO

EXEC sp_addlinkedsrvlogin 
    @rmtsrvname = '<server address>', 
    @useself = 'FALSE', 
    @locallogin=NULL,
    @rmtuser = '<username>',
    @rmtpassword = '<password>'
GO

select * from [MyExternalServer].[<database name>].[<schema>].[<table name>]

Whereas for Azure SQL:

CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<password>'; 
CREATE DATABASE SCOPED CREDENTIAL ElasticDBQueryCred 
WITH IDENTITY = '<username>', 
SECRET = '<password>';  

CREATE EXTERNAL DATA SOURCE MyElasticDBQueryDataSrc WITH 
    (TYPE = RDBMS, 
    LOCATION = '<server>', 
    DATABASE_NAME = '<database name>', 
    CREDENTIAL = ElasticDBQueryCred, 
) ; 


create schema <internalschema>

CREATE EXTERNAL TABLE <internalschema>.<internaltablename>
(
    ... // list of columns
WITH 
( DATA_SOURCE = MyElasticDBQueryDataSrc,
SCHEMA_NAME = <schema>,
OBJECT_NAME = <table name>
) 

select * from <internalschema>.<internaltablename>

The challenge now is to make the database scripts be common using both approaches. To reference a table using Linked Server, it has to be addressed using four-part identifier [server].[database].[schema].[tablename]. Contrast this with external data source where it can be addressed just by using [schema].[tablename].

Using inspiration from this question: https://dba.stackexchange.com/questions/74566/sql-server-using-4-part-identifiers-when-database-may-be-on-the-same-server, my approach is to create a synonym on my local database that redirects [schema].[tablename] to [externalserver].[externaldatabase].[externalschema].[tablename].

i.e. locally:

create schema <internalschema>
CREATE SYNONYM <internalschema>.<internaltablename> FOR [MyExternalServer].[<database name>].[<schema>].[<table name>]

After which, the same statement would work for both cases:

select * from <internalschema>.<internaltablename>

EDIT: One big problem with this approach is that you cannot use wrap your script under distributed transaction, because Azure SQL does not allow DTC.




回答2:


if we are talking about SQL Server, external data source/table/file format are supported starting from SQL Server 2016 - https://msdn.microsoft.com/en-us/library/dn935022.aspx .



来源:https://stackoverflow.com/questions/36735179/sql-server-express-equivalent-for-external-data-source

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!