Ser*_*kin 5 sql-server linked-server update sql-server-2022
将 SQL Server 从 2019 年升级到 2022 后,以下使用链接服务器的查询开始失败(为了简单起见,我省略了一些列名称和详细信息):
UPDATE [<remote server>].[<remote db>].dbo.Projects
SET RemoteColumnName = p.LocalColumnName
FROM prod.Projects p
WHERE p.ProjectID = Projects.ProjectID;
Run Code Online (Sandbox Code Playgroud)
然而,不涉及本地表工作的基本更新就很好了。SQL Server 报告以下错误,我什至在文档中找不到该错误:
UPDATE [<remote server>].[<remote db>].dbo.Projects
SET RemoteColumnName = p.LocalColumnName
FROM prod.Projects p
WHERE p.ProjectID = Projects.ProjectID;
Run Code Online (Sandbox Code Playgroud)
两台服务器都是 SQL Server 2022,在升级之前一切正常。
为本地和远程表添加 DDL,以防万一。但是,问题似乎与模式无关,并且在具有不同数据类型的不同表上重现。
-- Table on the remote linked server
CREATE TABLE dbo.Projects
(
ProjectID BIGINT NOT NULL,
RemoteColumnName VARCHAR(255) NOT NULL,
CONSTRAINT PK_Projects PRIMARY KEY CLUSTERED (ProjectID)
)
-- Table on the local server
CREATE TABLE prod.Projects
(
ProjectID BIGINT NOT NULL,
LocalColumnName VARCHAR(255) NOT NULL,
CONSTRAINT PK_Projects PRIMARY KEY CLUSTERED (ProjectID)
)
Run Code Online (Sandbox Code Playgroud)
添加链接服务器定义脚本。帐户RemoteUser具有远程服务器上目标数据库的 db_owner 角色。两个数据库的兼容级别均为 160。即使在空表上也会重现该问题。
EXEC master.dbo.sp_addlinkedserver @server = N'IS', @srvproduct=N'SQL Server'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'IS',@useself=N'False',@locallogin=NULL,@rmtuser=N'RemoteUser',@rmtpassword='########'
GO
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'collation compatible', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'data access', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'dist', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'pub', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'rpc', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'rpc out', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'sub', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'connect timeout', @optvalue=N'0'
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'collation name', @optvalue=NULL
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'lazy schema validation', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'query timeout', @optvalue=N'0'
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'use remote collation', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'IS', @optname=N'remote proc transaction promotion', @optvalue=N'false'
Run Code Online (Sandbox Code Playgroud)
如果您对调用数据库中的任何表(而不仅仅是您在查询中引用的表)使用动态数据屏蔽,则会出现此错误。
在调用数据库中曾经使用过 DDM就足够了。一旦使用,即使删除使用 DDM 的每个表,错误仍然存在。我还没有找到重置此状态的方法。
您可以使用该文档链接中的查询来检查使用 DDM 的表:
SELECT c.name, tbl.name as table_name, c.is_masked, c.masking_function
FROM sys.masked_columns AS c
JOIN sys.tables AS tbl
ON c.[object_id] = tbl.[object_id]
WHERE is_masked = 1;
Run Code Online (Sandbox Code Playgroud)
此错误是意外行为,您应该向 Microsoft 支持报告,以便他们调查修复。
在修复可用之前,可以采取多种解决方法,包括按照您的建议用删除和插入序列替换更新。
另一种选择是将匹配的源行复制到临时表或表变量,并在更新中引用它,而不是直接引用源表:
SELECT P.*
INTO #Projects
FROM prod.Projects AS P
WHERE EXISTS
(
SELECT *
FROM [<remote server>].[<remote db>].dbo.Projects AS RP
WHERE RP.ProjectID = P.ProjectID
);
UPDATE RP
SET RP.RemoteColumnName = P.LocalColumnName
FROM #Projects AS P
JOIN [<remote server>].[<remote db>].dbo.Projects AS RP
ON RP.ProjectID = P.ProjectID;
Run Code Online (Sandbox Code Playgroud)
对于那些感兴趣的人,编译期间第二次调用ExtractSourceNames时会发生错误:
| 归档时间: |
|
| 查看次数: |
1143 次 |
| 最近记录: |