SQL 外部数据源的 Server Express 等价物
SQL Server Express equivalent for EXTERNAL DATA SOURCE
根据https://azure.microsoft.com/en-us/documentation/articles/sql-database-elastic-query-getting-started-vertical/,Azure SQL 中的一个数据库现在可以查询其他Azure SQL 数据库。对于我的用例,我计划让一个数据库为其他数据库提供参考数据,这非常适合拓扑 1(垂直分片)。
这非常适合部署环境,但对于本地开发,我通常使用 SQL Server Express 进行开发。从 SQL Server 2012 Express 开始,CREATE EXTERNAL DATA SOURCE
不是有效语法。
本地开发是否也可以从外部数据源中获益?
如果我们谈论的是 SQL 服务器,则从 SQL Server 2016 - https://msdn.microsoft.com/en-us/library/dn935022.aspx 开始支持外部数据 source/table/file 格式。
权衡功能集后,我决定区分本地数据库和 Azure SQL 的设置。
- 当本地 SQL 服务器数据库想要引用 Azure SQL 数据库时,可以使用链接服务器
- 当一个 Azure SQL 数据库想要引用另一个 Azure SQL 数据库时,只有这样它才会使用外部数据源
即本地
-- 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>]
而对于 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>
现在的挑战是使用这两种方法使数据库脚本通用。要使用链接服务器引用 table,必须使用四部分标识符 [server].[database].[schema].[tablename]
对其进行寻址。将此与外部数据源进行对比,外部数据源只需使用 [schema].[tablename]
.
即可解决
从这个问题中得到灵感:https://dba.stackexchange.com/questions/74566/sql-server-using-4-part-identifiers-when-database-may-be-on-the-same-server,我的方法是在我的本地数据库上创建一个同义词,将 [schema].[tablename]
重定向到 [externalserver].[externaldatabase].[externalschema].[tablename]
。
即本地:
create schema <internalschema>
CREATE SYNONYM <internalschema>.<internaltablename> FOR [MyExternalServer].[<database name>].[<schema>].[<table name>]
之后,相同的语句将适用于两种情况:
select * from <internalschema>.<internaltablename>
编辑:
这种方法的一个大问题是您不能在分布式事务下使用包装脚本,因为 Azure SQL 不允许 DTC。
根据https://azure.microsoft.com/en-us/documentation/articles/sql-database-elastic-query-getting-started-vertical/,Azure SQL 中的一个数据库现在可以查询其他Azure SQL 数据库。对于我的用例,我计划让一个数据库为其他数据库提供参考数据,这非常适合拓扑 1(垂直分片)。
这非常适合部署环境,但对于本地开发,我通常使用 SQL Server Express 进行开发。从 SQL Server 2012 Express 开始,CREATE EXTERNAL DATA SOURCE
不是有效语法。
本地开发是否也可以从外部数据源中获益?
如果我们谈论的是 SQL 服务器,则从 SQL Server 2016 - https://msdn.microsoft.com/en-us/library/dn935022.aspx 开始支持外部数据 source/table/file 格式。
权衡功能集后,我决定区分本地数据库和 Azure SQL 的设置。
- 当本地 SQL 服务器数据库想要引用 Azure SQL 数据库时,可以使用链接服务器
- 当一个 Azure SQL 数据库想要引用另一个 Azure SQL 数据库时,只有这样它才会使用外部数据源
即本地
-- 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>]
而对于 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>
现在的挑战是使用这两种方法使数据库脚本通用。要使用链接服务器引用 table,必须使用四部分标识符 [server].[database].[schema].[tablename]
对其进行寻址。将此与外部数据源进行对比,外部数据源只需使用 [schema].[tablename]
.
从这个问题中得到灵感:https://dba.stackexchange.com/questions/74566/sql-server-using-4-part-identifiers-when-database-may-be-on-the-same-server,我的方法是在我的本地数据库上创建一个同义词,将 [schema].[tablename]
重定向到 [externalserver].[externaldatabase].[externalschema].[tablename]
。
即本地:
create schema <internalschema>
CREATE SYNONYM <internalschema>.<internaltablename> FOR [MyExternalServer].[<database name>].[<schema>].[<table name>]
之后,相同的语句将适用于两种情况:
select * from <internalschema>.<internaltablename>
编辑: 这种方法的一个大问题是您不能在分布式事务下使用包装脚本,因为 Azure SQL 不允许 DTC。