【问题标题】:SQL set variable as the result of a query in a stored procedureSQL 将变量设置为存储过程中的查询结果
【发布时间】:2016-05-03 22:05:38
【问题描述】:

我正在创建一个带有游标的存储过程,我需要将列的数量存储到一个变量中。 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

【问题讨论】:

  • 不能这样运行动态SQL,需要使用sp_executesql
  • 还简化了 SQL Select Count(distinct MyFirstSQLFieldName) 将完成这项工作。
  • @JamesZ 我从另一个同事那里找到了一些存储过程,他使用 Exec(@requestSQL) 并且工作正常。
  • 是的,你也可以使用 exec,但是 sp_executesql 通常是一个更好的选择,因为你可以使用变量而不需要进行字符串连接(但不是例如表名)

标签: sql-server tsql variables stored-procedures


【解决方案1】:

另一个更安全的选择是使用类似这样的 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

【讨论】:

  • 谢谢阿里,为什么当我执行 Exec sp_executesql 时,我得到了正确的结果,然后当我运行 select @Quantity 时,值为 null ?
  • 您确定您使用的是OUTPUT 子句吗?
  • 是的,我确实使用了 OUTPUT 关键字。我已将您的代码复制/粘贴到我的代码中。
  • 好吧,我发现我的错误了,我的 tableName 是 report.report_table1 并且它不起作用,因为第一个报告是数据库的架构,我必须在表名前添加方括号。跨度>
【解决方案2】:
Set @Quantite = (@ReqSQLQuantite)

这不是评估,是隐式转换。从 NVARCHAR 到 INT,并且您试图将 SQL 查询文本转换为 INT,因此出现错误。

此外,您假设 results 与返回值相同并且可以分配给变量。这是不正确的,SQL 执行结果被发送到客户端。要捕获结果,您必须使用 SELECT 分配:SELECT @value =...。尝试运行@variable = EXEC(...)同一件事。以与应用程序中的打印相同的方式思考 SELECT 结果:打印将一些文本发送到控制台。如果你运行一些像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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 2019-12-29
    相关资源
    最近更新 更多