Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.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 server SQL设置变量作为存储过程中查询的结果_Sql Server_Tsql_Variables_Stored Procedures - Fatal编程技术网

Sql server SQL设置变量作为存储过程中查询的结果

Sql server SQL设置变量作为存储过程中查询的结果,sql-server,tsql,variables,stored-procedures,Sql Server,Tsql,Variables,Stored Procedures,我正在创建一个带有游标的存储过程,需要将列的数量存储到变量中。 SQL表示它无法将nvarchar转换为int 我曾尝试使用CONVERT、CAST和EXEC,但无法使其正常工作。 我怎样才能解决这个问题 DECLARE @FieldName nvarchar(255); DECLARE @RequestCode Nvarchar(50); DECLARE @ReqSQLQuantity nvarchar(max); DECLARE @Quantity int; Select @ReqSQLQ

我正在创建一个带有游标的存储过程,需要将列的数量存储到变量中。 SQL表示它无法将nvarchar转换为int 我曾尝试使用CONVERT、CAST和EXEC,但无法使其正常工作。 我怎样才能解决这个问题

DECLARE @FieldName nvarchar(255);
DECLARE @RequestCode Nvarchar(50);
DECLARE @ReqSQLQuantity nvarchar(max);
DECLARE @Quantity int;

Select @ReqSQLQuantity = concat('select count(*) From (select distinct [', @FieldName , '] from [report_' , @RequestCode , ']) as number')
Set @Quantity = (@ReqSQLQuantity)
Select @Quantity
这不是一个计算,而是一个隐式转换。从NVARCHAR到INT,并且您试图将SQL查询文本转换为INT,因此会出现错误

此外,您假设结果与返回值相同,并且可以分配给变量。这是不正确的,SQL执行结果被发送到客户端。要捕获结果,必须使用SELECT赋值:
SELECT@value=…
。尝试运行
@variable=EXEC(…)
不是一回事。在选择结果时思考与在应用程序中打印相同的方式:打印将一些文本发送到控制台。如果您运行一些伪代码,比如
x=print('foo')
,那么“foo”被发送到控制台,x包含print返回的值(不管是什么)。与此伪SQL相同,
@x=EXEC('SELECT foo')
将向客户端发送
foo
,并且@x将发送一些数值,该数值是EXEC返回的值(在正确的示例中,必须使用显式
RETURN
语句来设置它)

总的来说,发布的代码完全不需要捕获并返回值,它可以简单地执行动态SQL并将结果返回给客户端:

SET @sql = concat(N'SELECT count(*) FROM (SELECT ... FROM ...)');
exec sp_executesql @sql;

另一个稍微安全一点的选择是使用sp_executesql存储过程,如下所示

DECLARE @FieldName nvarchar(255);
DECLARE @RequestCode Nvarchar(50);
DECLARE @ReqSQLQuantity nvarchar(max);
DECLARE @Quantity int, @tableName SYSNAME;

SET @tableName = N'report_' + @RequestCode

Select @ReqSQLQuantity = N'  select @Quantity = count(*) '
                        + N' From (select distinct ' + QUOTENAME(@FieldName)  
                        + N' from ' + QUOTENAME(@tableName) + N' ) as number'
Exec sp_executesql @ReqSQLQuantity
                  ,N'@Quantity INT OUTPUT'
                  ,@Quantity OUTPUT

Select @Quantity

您不能像那样运行动态SQL,您需要使用sp_executesql并简化SQL选择计数(不同的MyFirstSQLFieldName)将完成此工作。@JamesZ我从另一位同事那里找到了一些存储过程,他在那里使用Exec(@requestSQL),并且工作正常。是的,您也可以使用Exec,但是sp_executesql通常是一个更好的选择,因为您可以使用变量,而无需进行字符串连接(但不包括表名)。感谢Ali,为什么我执行Exec sp_executesql时,结果正确,然后在运行select@Quantity时,该值为空?您确定使用的是
OUTPUT
子句吗?是的,我使用的是OUTPUT关键字。我已将您的代码复制/粘贴到我的代码中。好的,我发现了我的错误,我的表名是report.report\u table1,但它不起作用,因为第一个报表是数据库的架构,我必须在表名之前添加方括号。
DECLARE @FieldName nvarchar(255);
DECLARE @RequestCode Nvarchar(50);
DECLARE @ReqSQLQuantity nvarchar(max);
DECLARE @Quantity int, @tableName SYSNAME;

SET @tableName = N'report_' + @RequestCode

Select @ReqSQLQuantity = N'  select @Quantity = count(*) '
                        + N' From (select distinct ' + QUOTENAME(@FieldName)  
                        + N' from ' + QUOTENAME(@tableName) + N' ) as number'
Exec sp_executesql @ReqSQLQuantity
                  ,N'@Quantity INT OUTPUT'
                  ,@Quantity OUTPUT

Select @Quantity