使用变量作为条件时,链接服务器上的OPENQUERY删除操作失败
带条件的OPENQUERY删除语句执行失败
可正常运行的语句
1. 无条件删除远程表数据
Delete OPENQUERY ([MyLinkedServer], 'SELECT * FROM db_from_sap_for_bi.VBRK')
2. 带条件查询远程表数据
DECLARE @DateDailyUpdate as nvarchar(10) set @DateDailyUpdate= (select DateDailyUpdate from tblDateFilter Where TableName='VBRK') DECLARE @TSQL varchar(8000), @VAR char(2) SELECT @TSQL = 'select * FROM OPENQUERY([MyLinkedServer],''Select * FROM db_from_sap_for_bi.VBRK WHERE FKDAT >= ''''' + @DateDailyUpdate + ''''''')' EXEC (@TSQL)
执行报错的删除语句
SELECT @TSQL = 'Delete OPENQUERY([MyLinkedServer],''Select * FROM db_from_sap_for_bi.VBRK WHERE FKDAT >= ''''' + @DateDailyUpdate + ''''''')'
报错提示
链接服务器"MyLinkedServer"的OLE DB提供程序"MSDASQL"无法从表"Select * FROM db_from_sap_for_bi.VBRK WHERE FKDAT >= '20230930'"中删除数据。发生了可恢复的提供程序特定错误,例如RPC失败。
问题原因及解决办法
问题核心是DELETE结合OPENQUERY时的语法逻辑错误:当用OPENQUERY作为DELETE的目标时,OPENQUERY内部的语句得是能直接被识别为可更新数据集的表达式,而不是嵌套的SELECT *查询。你当前的写法里,MSDASQL驱动把整个SELECT * ...的字符串当成了表名,自然找不到对应的表来删除。
正确的写法有两种:
写法一:在OPENQUERY内直接写DELETE语句
DECLARE @DateDailyUpdate as nvarchar(10) set @DateDailyUpdate= (select DateDailyUpdate from tblDateFilter Where TableName='VBRK') DECLARE @TSQL varchar(8000) SELECT @TSQL = 'EXEC OPENQUERY([MyLinkedServer],''DELETE FROM db_from_sap_for_bi.VBRK WHERE FKDAT >= ''''' + @DateDailyUpdate + ''''''')' EXEC (@TSQL)
写法二:让OPENQUERY返回过滤后的可更新行集,再在外层DELETE
DECLARE @DateDailyUpdate as nvarchar(10) set @DateDailyUpdate= (select DateDailyUpdate from tblDateFilter Where TableName='VBRK') DECLARE @TSQL varchar(8000) SELECT @TSQL = 'DELETE FROM OPENQUERY([MyLinkedServer],''SELECT * FROM db_from_sap_for_bi.VBRK WHERE FKDAT >= ''''' + @DateDailyUpdate + ''''''')' EXEC (@TSQL)
这两种写法都能让驱动正确识别要删除的目标数据集,避免把查询语句当成表名的错误。
内容的提问来源于stack exchange,提问作者Sixthsense
相关产品推荐
相关产品推荐

