我正在实施一项新功能,该功能需要来自多台服务器上的数据库的数据。我只需要合并来自所有这些服务器的数据并对其进行排序。想到的两个选项是:
使用链接服务器并编写一个简单的查询来合并和排序将从一台服务器运行并从其他服务器收集数据的数据。
使用应用程序从所有服务器收集数据,并将其发送回 SQL Server 进行排序(不想在应用程序中实现排序)。
我们在 SQL Server 2008 r2 的主动/主动集群中运行我们的服务器。所有数据库都具有相同的权限,如果您有权访问一个数据库/服务器,则您对它们都有权限。这是一个面向公众的应用程序(需要用户登录)。
使用链接服务器有哪些风险?是否有任何我应该关注的安全漏洞?在主动/主动集群中运行链接服务器是否有任何问题?与替代方案相比,是否存在任何重大的性能问题?
关于链接服务器似乎有普遍的负面“嗡嗡声”,但我找不到任何具体的东西让我相信那里有任何真正的担忧。
performance sql-server-2008 security sql-server linked-server
我有一个我试图OPENQUERY在 SSRS/SQL Server 2014 上运行的查询,但我不断收到以下错误:
以 [...] 开头的字符串太长。最大长度为 8000。
有什么办法可以解决这个限制吗?
作为参考,我正在尝试通过链接的 MySQL 服务器从 SSRS 运行查询。
我有一个运行数据库的 SQL Server 2008,我想放入 TFS。因此,我使用了导入数据库的 Visual Studio 2013 数据库项目。修复了一堆错误后,我只剩下一个错误:
在一个视图中,开发人员用于OPENQUERY访问链接服务器。因此,我导入了一个包含正确数据库的 DACPAC,并Add Database Reference使用以下参考选项将其添加到项目中。

这是原始视图创建的较短版本:
CREATE VIEW dbo.vwStatus
AS
SELECT StatusID, StatusName
FROM OPENQUERY(LinkedServer, 'SELECT * FROM [DB].[dbo].tbStatus') AS derivedtbl_1
Run Code Online (Sandbox Code Playgroud)
这导致以下错误:
错误 136 SQL71501:视图:[dbo].[vwStatus] 具有对对象 [LinkedServer] 的未解析引用。
所以我尝试插入服务器名称变量
FROM OPENQUERY($(LinkedServer), 'SELECT * FROM [DB].[dbo].tbStatus') AS derivedtbl_1
Run Code Online (Sandbox Code Playgroud)
这导致
错误 176 SQL46010:$(LinkedServer) 附近的语法不正确。
我稍微摆弄了一下并尝试了以下操作(启用和不启用带引号的标识符):
FROM OPENQUERY("$(LinkedServer)", 'SELECT * FROM [DB].[dbo].tbStatus') AS
FROM OPENQUERY([$(LinkedServer)], 'SELECT * FROM [DB].[dbo].tbStatus') AS
FROM OPENQUERY([LinkedServer], 'SELECT * FROM [DB].[dbo].tbStatus') AS
FROM …Run Code Online (Sandbox Code Playgroud) 我一直在使用旧提供程序 (SQLNCLI) 的链接服务器,没有任何问题,正如Microsoft推荐的那样,我计划切换到新提供程序 (MSOLEDBSQL)。安装驱动程序后,我可以使用以下 T-SQL 添加链接服务器
EXEC sp_addlinkedserver
@server=N'SQL02\DEV1',
@srvproduct=N'',
@provider=N'MSOLEDBSQL',
@datasrc=N'SQL02,1933';
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我尝试查询新的链接服务器时出现以下错误:
我试过的查询:
--- example 1
select * from OPENQUERY ([SQL02\DEV1], 'select name from sys.databases');
--- example 2
select name from [SQL02\DEV1].master.sys.databases;
--- example 3 (without linked server dependency)
SELECT c.* FROM OPENROWSET(
'MSOLEDBSQL'
, 'Server=SQL02,1933;Database=master;Integrated Security=True;'
, 'SELECT name FROM sys.databases;'
) c;
Run Code Online (Sandbox Code Playgroud)
从所有示例中得到相同的错误:
不支持 OLE DB 提供程序“MSOLEDBSQL”与 SQL Server 的进程外使用。
这是否真的意味着 SQL-2016 不支持使用新的提供程序 MSOLEDBSQL,尤其是在链接服务器中,或者除了重新安装驱动程序和重新启动 SQL Server 之外,我还有什么遗漏。
我有一个指向链接服务器的存储过程。在整个过程中的几个地方,我得到了如下内容:
INSERT INTO [TableName]
(...Columns...)
SELECT ...Columns...
FROM [ServerName\InstanceName].[Catalogue].[dbo].[TableName]
WHERE TableNameID = @TableNameID
Run Code Online (Sandbox Code Playgroud)
这个过程存在于我的开发环境、测试环境和实时环境中。
问题是该过程的每个副本都略有不同,因为每个环境的服务器名称都不同。这使得管理脚本更新的部署变得很麻烦。
有没有办法使程序可移植,以便每个环境都可以运行相同版本的程序?
如果没有,我可以做些什么来使脚本部署更不容易出错/错误?
我让用户看到了他们不应该看到的链接服务器。
链接服务器被定义为只有我可以访问它,但每个人都可以看到和使用它。
我使用以下步骤创建了新的链接服务器:
Server Objects,右击Linked Servers和左键单击New Linked Server...General选项卡中选择SQL Server了Server type和写入服务器的名称Security上半部分的选项卡下单击Add,选择“sa”为Local Login,输入Remote User名称和Remote PasswordSecurity下部选项卡下(下For a login not defined in the list above, connections will:)选择第一个选项:Not be madeOK并开始测试现在唯一应该看到链接服务器的人是我(“sa”),但不知何故其他用户可以看到并使用它。
注1:可以使用链接服务器的用户在远程服务器上有权限,他们不会看到他们不应该看到的数据,他们只能在他们不应该看到的时候从链接服务器访问它。
注 2:我是这sysadmin两个实例中唯一的一个。
我们的产品基于 Microsoft SQL Server。目前,我们使用了三个数据库,并且始终将它们部署在一个 SQL Server 实例上。
这三个数据库是OLTP、OLAP和审计。OLAP 数据库有大量来自 OLTP 和审计的 EOD 入站数据,使用跨数据库查询。
如果我们将这三个数据库部署到单个物理服务器内的三个独立的标准版实例上,并使用 SQL Server 的链接服务器功能将它们绑定在一起:
目前,我们正在向拥有 500 多个并发用户的潜在客户进行宣传。
我们正在起草服务器规范,其中包括 64 个内核和 256GB RAM。为了让 SQL Server 能够利用所有这些丰富的资源,客户必须购买企业版,而对于 SQL Server 2016,它仅在基于每核的许可中可用。
我们担心仅许可成本(64 x 7400 美元)就会让他们失望。所以我想把数据库拆分成三个标准版的实例,并把它们链接在一起,希望链接功能对应用程序代码是透明的。
经过大约 3 天的尝试,我无法创建从 SQL Server 2016 到 Informix 11.5 的链接服务器。我没有在其他版本(2008R2 等)上尝试过这个,因为我想先在测试环境中设置连接。
我做了什么
1) 将 IBM Informix指令与 OLE DB 提供程序一起使用,在其中我收到以下错误(无论我是否在提供程序字符串中使用 DNS):
无法为链接服务器“UCCX”初始化 OLE DB 提供程序“Ifxoledbc”的数据源对象。链接服务器“UCCX”的 OLE DB 提供程序“Ifxoledbc”返回消息“EIX000: (-23197)”数据库区域设置信息不匹配”(Microsoft SQL Server,错误:7303)
DB Locale 是 en_US.57372
2)如本博客所述,使用 Microsoft OLE DB Provider for SQL Server返回错误:
命名管道提供程序:无法打开与 SQL Server 的连接。链接服务器 UCCX 的 OLE DB 提供程序 SQLNCLI11 返回消息“登录超时已过期” 链接服务器 UCCX …
我在同一个域中有两个 SQL Server 2016 标准版服务器。ServerA有两个链接服务器连接设置到ServerB。
第一个链接服务器连接使用专用的远程SQL 登录安全上下文。那个一直是并且仍然工作正常。
第二个连接使用“登录的当前安全上下文”,它是ServerA 上的Windows 身份验证 (AD) 登录。直到今天,这也运行良好。
今天突然间,连接到 ServerA 然后尝试运行使用第二个链接服务器连接的查询的每个人最终都会遇到以下错误:
链接服务器“LinkedServerName”的 OLE DB 访问接口“SQLNCLI11”返回消息“无法生成 SSPI 上下文”。消息 -2146893044,级别 16,状态 1,第 0 行 SQL Server 网络接口:登录尝试失败
此外,用户目前可以直接连接到 ServerA 和 ServerB,甚至可以直接对 ServerB 上的对象执行查询,但是当他们尝试通过 ServerA 上的链接服务器运行引用 ServerB 上相同对象的查询时,这是唯一一次他们得到上述错误,目前。
这是我们目前看到的SPN和日志(抱歉所有混淆):
ServerB 成功的 SPN 注册 SQL 日志:
ServerB 成功的 SPN 注册 SQL 日志:
ServerA 注册的 SPN:
我对 SQL 链接服务器的特定主键使用简单的更新语句,如下所示
UPDATE t
SET
processed = 1,
processed_on = GETDATE()
FROM [LINKED\SERVER].DATABASE.dbo.FileQueue t
WHERE t.FileId = '3b33eff6-fde1-4e8c-9c23-2dbd45f50222'
Run Code Online (Sandbox Code Playgroud)
两台服务器都是SQL Server 2019。表定义是
CREATE TABLE dbo.FileQueue
(
FileId UNIQUEIDENTIFIER NOT NULL,
Processed BIT NOT NULL,
Processed_on DATETIME NULL
CONSTRAINT PK_FileQueue PRIMARY KEY CLUSTERED
(
FileId ASC
)
)
Run Code Online (Sandbox Code Playgroud)
已处理列具有位类型。由于全表扫描,查询速度很慢。
为什么会发生这种情况?当我从语句中删除位列时,读取和更新单个远程行一切正常。
该Id列是聚集主键。我有很多带有相似键的表。
我尝试使用CONVERTorCAST函数,结果是相同的。
对于没有位列的查询,执行计划非常好。
UPDATE t
SET
--processed = 1,
-- any other columns can be added to be updated except bit
processed_on = GETDATE()
FROM …Run Code Online (Sandbox Code Playgroud) linked-server ×10
sql-server ×9
performance ×2
security ×2
errors ×1
informix ×1
logon ×1
ssdt ×1
ssms ×1
ssrs ×1
update ×1
view ×1