我找到了指南将动态 SQL 存储过程的结果输出到变量中,但我的问题的棘手部分是我正在使用
OPENQUERY
,这使得使用动态 SQL 更具挑战性。
当我尝试执行下面的尝试时,会出现错误:
“@LinkedServer”附近的语法不正确
CREATE PROCEDURE [dbo].[DateLastUsage]
(@Part nvarchar(50),
@LinkedServer nvarchar(50),
@DateLastUsage datetime2 OUTPUT)
AS
BEGIN
DECLARE @SQL nvarchar(4000)
SET @SQL = N'SELECT TOP 1 @DateLastUsage = DateLastUsage FROM OPENQUERY(@LinkedServer, ''SELECT MAX(date_history) DateLastUsage FROM v_inventory_hist WHERE part = ''@Part'' '' )'
EXEC sp_executesql @SQL, N'@LinkedServer nvarchar(50), @Part nvarchar(50), @DateLastUsage datetime2 output', @LinkedServer = @LinkedServer, @Part = @Part, @DateLastUsage = @DateLastUsage output
END
DECLARE @DateLastUsage datetime2
EXEC dbo.GSSDateLastUsage 'PartA', 'GSS', @DateLastUsage OUTPUT
SELECT @DateLastUsage
不接受变量作为其参数。OPENQUERY
因此您还需要使用动态 SQL。例如:
set @SQL = N'
select top 1 @DateLastUsage = DateLastUsage
from openquery(' + QUOTENAME(@LinkedServer) + ', ''select max(date_history) DateLastUsage from v_inventory_hist where part = ''' + QUOTENAME(@Part, '''') + ''' '' )
';
注意
@Part
直接嵌入到查询中的方式,否则它也不起作用/
但说实话,无论如何都不清楚你为什么要使用
OPENQUERY
。可以直接查询链接服务器from linkedserver...v_inventory_hist
。现在就可以正确传递参数了。
CREATE OR ALTER PROCEDURE dbo.DateLastUsage
@Part nvarchar(50)
, @LinkedServer sysname
, @DateLastUsage datetime2 output
AS
DECLARE @SQL nvarchar(max) = N'
SELECT @DateLastUsage = MAX(date_history)
FROM ' + QUOTENAME(@LinkedServer) + '...v_inventory_hist
WHERE part = @Part;
';
EXEC @SQL,
N'@Part nvarchar(50),
@DateLastUsage datetime2 output',
@Part = @Part,
@DateLastUsage = @DateLastUsage output;
或者,如果链接服务器也是 SQL Server,您可以构造一个
@proc
变量,该变量指向远程服务器上的 sp_executesql
。
CREATE OR ALTER PROCEDURE dbo.DateLastUsage
@Part nvarchar(50)
, @LinkedServer sysname
, @DateLastUsage datetime2 output
AS
DECLARE @SQL nvarchar(max) = N'
SELECT @DateLastUsage = MAX(date_history)
FROM v_inventory_hist
WHERE part = @Part;
';
DECLARE @proc nvarchar(1000) = QUOTENAME(@LinkedServer) + '..sys.sp_executesql';
EXEC @proc @SQL,
N'@Part nvarchar(50),
@DateLastUsage datetime2 output',
@Part = @Part,
@DateLastUsage = @DateLastUsage output;
另请注意数据类型分别更改为
sysname
和 `nvarchar(max)1。