【问题标题】:Stored procedure to Linked server with parameters - Error带有参数的链接服务器的存储过程 - 错误
【发布时间】:2018-09-12 21:33:46
【问题描述】:

我正在尝试为链接服务器创建存储过程,其中输入参数@ServerName 是我使用的链接服务器的名称。 在这个过程中,我还声明了我想从动态 SQL 查询和行中获取哪个值的参数。

CREATE PROC sp_Version @ServerName varchar(30)
作为
声明 @Ver varchar(10)
exec ('select @Ver from openquery(' + @ServerName + ', ''SELECT SUBSTRING (@@VERSION, 22, 7) = @Ver''')

当我执行我的 sp 时,我收到一条错误消息:

“必须声明标量变量“@Ver”。”

你能帮帮我吗?

【问题讨论】:

  • 对于用户存储过程,使用sp_ 不是一个好习惯,您正在为此服务器声明@ver,过程期望在链接服务器中看到变量
  • “程序期望在链接服务器中看到变量”你的意思是“声明@Ver varchar(10)”我为我的本地服务器声明了变量,但不是链接服务器或类似的东西那个?
  • 您的变量 @Ver 在动态 SQL 中无法访问,因为它是作为单独的范围(使用 EXEC)执行的。您应该使用过程 sp_executesql 并将 @ver 值作为输出参数输出。
  • 不要使用sp_ 作为存储过程的前缀,尤其是不要使用像sp_version 那样具有潜在冲突价值的名称。 See also。此外,SUBSTRING 方法存在缺陷——在我的服务器上我得到了2017 (R,这可能不是您想要的。看看SERVERPROPERTY('ProductVersion') 之类的东西。正如其他人所提到的,你不能像这样远程变量——看看INSERT .. EXEC

标签: sql sql-server tsql stored-procedures linked-server


【解决方案1】:

我不确定您使用@Ver 的值的目的是什么,也许是OUTPUT 参数?如果是这样,那么语法将是:

CREATE PROC GetVersion @ServerName varchar(30), @Ver nvarchar(500) OUTPUT AS

    DECLARE @SQL nvarchar(MAX);

    SET @SQL = N'SELECT @dVer = Version' + NCHAR(10) +
               N'FROM OPENROWSET(''SQLNCLI'',' + NCHAR(10) +
               N'                ' + QUOTENAME('Server=' + @ServerName + ';Trusted_Connection=YES;','''') + ',' +NCHAR(10) +
               N'                ''SELECT @@VERSION AS Version'');';

    PRINT @SQL;
    EXEC sp_executesql @SQL, N'@dVer nvarchar(500) OUTPUT', @dVer = @Ver OUTPUT;


GO

DECLARE @ver varchar(500)

EXEC GetVersion 'YourServerName', @ver OUTPUT;

PRINT @ver;
GO

DROP PROC GetVersion;

请注意,首先,我没有使用sp_ 前缀。我还使用了sp_executesql 而不是简单的EXEC(这通常是更好的做法,因为您可以像我所做的那样对动态SQL 进行参数化),并使用QUOTENAME 来尝试避免注入。

【讨论】:

    【解决方案2】:

    我遇到过几次这种情况。试试这个:

    CREATE PROC sp_Version @ServerName varchar(30)
    as
    Declare @Ver varchar(10)
    
    DECLARE @SqlCommand nvarchar(MAX)
    
    SET @SqlCommand = 'SELECT @Ver2 = SUBSTRING (@@VERSION, 22, 7) '
    
    DECLARE @sp_executesql VARCHAR(100)
    SET @sp_executesql = @ServerName + '.master.sys.sp_executesql'
    EXEC @sp_executesql @SqlCommand, N'@Ver2 nvarchar(10) out', @Ver out
    SELECT @Ver
    

    【讨论】:

    • 我收到一个错误:消息 2812,级别 16,状态 62,过程 usp_Version,第 17 行找不到存储过程''。
    • 它是否说它找不到哪个存储过程?在我的示例中,我有一个 sp_Version,您创建了 usp_Version(带有前导 'u')?
    • 是的,因为有人说“sp_”命名是一种不好的做法,因为用户不能说这个过程是系统过程还是用户过程
    • 是的,你是对的。我通常也使用usp,不知道为什么我没有在这个例子中使用。无论如何:它是否说它找不到哪个存储过程?
    猜你喜欢
    • 1970-01-01
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多