从使用动态 SQL 和 OPENQUERY 的存储过程输出变量

问题描述 投票:0回答:1

我找到了指南将动态 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
sql-server tsql dynamic-sql sql-server-2019
1个回答
0
投票

如记录:

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。

© www.soinside.com 2019 - 2024. All rights reserved.