Sql server SQL设置变量作为存储过程中查询的结果
我正在创建一个带有游标的存储过程,需要将列的数量存储到变量中。 SQL表示它无法将nvarchar转换为int 我曾尝试使用CONVERT、CAST和EXEC,但无法使其正常工作。 我怎样才能解决这个问题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
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