将 SQL 查询结果传递给存储过程参数

时间:2021-05-01 18:48:47

标签: sql-server

我有一个 SQL 查询,它在 varchar 中返回结果,然后我试图将该结果传递给存储过程参数,但出现错误

<块引用>

必须声明标量变量“@datev”

SQL:

DECLARE @datev varchar

SELECT
    CONVERT(varchar, (CASE
                         WHEN DATENAME (dw, GETDATE()) IN ('Thursday') 
                            THEN CONVERT (varchar, DATEADD(d, -6, GETDATE()), 112)
                         WHEN DATENAME (dw, GETDATE()) IN ('Friday') 
                            THEN CONVERT (varchar, DATEADD(d, -7, GETDATE()), 112) 
                         WHEN DATENAME (dw, GETDATE()) IN ('Saturday') 
                            THEN CONVERT (varchar, DATEADD(d, -8, GETDATE()), 112)
                         WHEN DATENAME (dw, GETDATE()) IN ('Sunday') 
                            THEN CONVERT (varchar, DATEADD(d, -9, GETDATE()), 112)
                         ELSE CONVERT(varchar, DATEADD(d, -((DATEPART (weekday, GETDATE()) + 1 + @@DATEFIRST) % 14), GETDATE()), 112) 
                      END), 112) AS rptdate 
INTO 
    #rwed

SELECT rptdate FROM #rwed

SELECT @datev = rptdate FROM #rwed

程序要调用:

EXEC Product_Movemnet1 @datev

1 个答案:

答案 0 :(得分:0)

如果您知道在哪里查看,文档中几乎可以找到任何解释。我想这就是搜索引擎的用途:-)

批次

为了重现该错误,我必须假设您正在两个不同的批次中运行您的两个查询:

  1. DECLARE @datev varchar ...
  2. EXEC Product_Movemnet1 @datev

定义批次

如果您使用 SQL Server Management Studio (SSMS) 来查询您的 Microsoft SQL Server 数据库,则可以通过多种方式定义批处理范围

  1. 按查询窗口:默认情况下,一个查询窗口中的所有SQL语句组成一批。

  2. 通过在查询之间添加 GO 语句,您可以对查询进行分组并定义单独的批次。

    GO documentation 摘录:

<块引用>

GO 向 SQL Server 实用程序发出一批 Transact-SQL 语句的结束信号。

  1. 在查询窗口中仅选择一部分 SQL 语句。

    SSMS shortcuts documentation 摘录:
<块引用>

如果未选择任何内容,则运行查询编辑器的选定部分或整个查询编辑器

变量

批处理范围与您问题中的错误有什么关系?好吧,您代码中的 @datev 称为变量。您定义它的方式使其成为局部变量

Variables documentation 摘录:

<块引用>

Transact-SQL 局部变量是可以保存特定类型的单个数据值的对象。

阅读变量的 DECLARE 语法,然后解释您的错误。

DECLARE documentation 摘录:

<块引用>

局部变量的作用域是声明它的批次。

换句话说:局部变量只存在于单个 SQL 语句批处理的生命周期内。

总结

执行声明变量、设置变量和批量使用变量的语句,可解决错误。

Fiddle 查看重现并解决的错误。


备注

您当前的解决方案可能不会产生您想要的结果(请参阅问题评论中有关数据类型 varchar 的备注,但未指定长度)。此外,它可以缩短一点:

-- attempt at improved version
-- + replace "varchar" with "varchar(10)"
-- + remove use of temporary table #rwed
-- + convert to string _once_
-- + replace "IN" with "=" for list with only one item

DECLARE @datev varchar(10);

SELECT @datev = CONVERT(varchar(10),
                   (CASE WHEN DATENAME(dw, GETDATE()) = 'Thursday' THEN DATEADD(d, -6, GETDATE())
                         WHEN DATENAME(dw, GETDATE()) = 'Friday'   THEN DATEADD(d, -7, GETDATE()) 
                         WHEN DATENAME(dw, GETDATE()) = 'Saturday' THEN DATEADD(d, -8, GETDATE())
                         WHEN DATENAME(dw, GETDATE()) = 'Sunday'   THEN DATEADD(d, -9, GETDATE())
                         ELSE DATEADD(d, -((DATEPART (weekday, GETDATE()) + 1 + @@DATEFIRST) % 14), GETDATE())
                      END), 112);

EXEC Product_Movement1 @datev;