Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用参数链接到服务器的存储过程-错误_Sql_Sql Server_Tsql_Stored Procedures_Linked Server - Fatal编程技术网

Sql 使用参数链接到服务器的存储过程-错误

Sql 使用参数链接到服务器的存储过程-错误,sql,sql-server,tsql,stored-procedures,linked-server,Sql,Sql Server,Tsql,Stored Procedures,Linked Server,我试图创建链接服务器的存储过程,输入参数@ServerName是我使用的链接服务器的名称。 在这个过程中,我还声明了要从动态SQL查询和行中获取的参数值 创建进程sp_Version@ServerName varchar30 像 声明@Ver varchar10 exec“从openquery中选择@Ver”++@ServerName+,选择子字符串@VERSION,22,7=@Ver” 当我执行sp时,我会收到一个错误消息: 必须声明标量变量@Ver 你能帮我吗?我不确定@Ver的值是什么,也

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

创建进程sp_Version@ServerName varchar30 像 声明@Ver varchar10 exec“从openquery中选择@Ver”++@ServerName+,选择子字符串@VERSION,22,7=@Ver”

当我执行sp时,我会收到一个错误消息:

必须声明标量变量@Ver


你能帮我吗?

我不确定@Ver的值是什么,也许是一个输出参数?如果是,那么语法将是:

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_uu前缀。我还使用了sp_executesql而不是简单的EXEC这通常是更好的做法,因为您可以像我所做的那样参数化您的动态SQL,并使用QUOTENAME来尝试避免注入。

我不确定@Ver的值(可能是一个输出参数)的目的是什么?如果是,那么语法将是:

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_uu前缀。我还使用了sp_executesql,而不是简单的EXEC。这通常是更好的做法,因为您可以像我所做的那样,参数化动态SQL,并使用QUOTENAME来尝试避免注入。

我曾多次遇到这种情况。试试这个:

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

这种情况我已经遇到过好几次了。试试这个:

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

对于用户存储过程,使用sp_10;不是一个好做法,您正在为此服务器声明@ver,过程希望在链接服务器中看到变量。过程希望在链接服务器中看到变量。您的意思是声明@ver varchar10,我为本地服务器声明了变量,但不适用于链接服务器或类似的东西?您的变量@Ver在动态SQL中不可访问,因为它是作为单独的作用域与EXEC一起执行的。您应该使用过程sp_executesql并将@ver值作为输出参数输出。不要将sp_uu用作存储过程的前缀,尤其是名称可能与sp_版本冲突的存储过程。此外,子字符串方法也有缺陷——在我的服务器上我得到了2017 R,这可能不是您想要的。看看SERVERPROPERTY'ProductVersion'之类的东西。正如其他人提到的,您不能像这样远程变量-看看INSERT。。EXEC.对于用户存储过程,使用sp_不是一个好做法,您正在为此服务器声明@ver,过程希望在链接服务器中看到变量procedure希望在链接服务器中看到变量您的意思是声明@ver varchar10我为本地服务器声明了变量,但不适用于链接服务器或类似的东西?您的变量@Ver在动态SQL中不可访问,因为它是作为单独的作用域与EXEC一起执行的。您应该使用过程sp_executesql并将@ver值作为输出参数输出。不要将sp_uu用作存储过程的前缀,尤其是名称可能与sp_版本冲突的存储过程。此外,子字符串方法也有缺陷——在我的服务器上我得到了2017 R,这可能不是您想要的。看看SERVERPROPERTY'ProductVersion'之类的东西。正如其他人提到的,您不能像这样远程变量-看看INSERT。。我得到一个错误:Msg 2812,级别16,状态62,过程usp\U版本,第17行找不到存储过程。它是否说找不到哪个存储过程?在我的示例中,我有一个sp_版本,您创建的usp_版本带有一个前导“u”?是的,因为有人说sp_命名是一种不好的做法,因为用户不能说这个过程是系统过程还是用户过程。是的,您是对的。我通常也使用usp,不知道为什么我没有在这个例子中使用。无论如何:它是否说找不到哪个存储过程?我得到一个错误:Msg 2812,16级,状态62,过程usp_版本,第17行找不到存储过程。它是否说找不到哪个存储过程?在我的示例中,我有一个sp_版本,您创建的usp_版本带有一个前导“u”?是的,因为有人说sp_命名是一种不好的做法,因为用户不能说这个过程是系统过程还是用户过程。是的,您是对的。我通常也使用usp,不知道为什么我没有在这个例子中使用。无论如何:它是否说明找不到哪个存储过程?