我在SQL Server中遇到问题。我必须使用作为系统过程的存储过程sp_executesql
,因为我在其上执行select子句的表取决于其他参数。
以下是样本:
@p_Origin
是我的程序中给出的参数,因此为了重现问题,我们将其声明为:
DECLARE @p_Origin nvarchar(255) = 'Sales'
我的SELECT
子句中也有一个参数,即目标表的列:
DECLARE @v_valueVersion as int
IF @p_Origin = 'Sales'
SET @v_valueVersion = (SELECT VersionId FROM Version WHERE ...)
ELSE IF
...
但是现在,我想从我的原始表中找回一个列,(这里是Sales
)
有了这个查询:
DECLARE @v_query as nvarchar(max) = 'SELECT MAX(Date) FROM dbo.' + @p_Origin + ' WHERE VersionId = ' + CAST(@v_valueVersion as nvarchar) + ' AND Month = CONVERT(NVARCHAR(6),GETDATE(),112) '
此列date
是datetime
列,在此处声明:(Month
列和date
列是两个不同的内容,它们不是参考同一时期)
DECLARE @v_maxDate as datetime
这是我的问题:
EXEC sp_executesql @v_query, N'@v_maxDate datetime out', @v_maxDate out
当我得到这个时,SELECT
子句给出了以下结果,这是一个好结果:
-----------------------
2016-01-19 15:49:58.000
但是当我PRINT
该值时,不打印任何内容,值为null
。如何使用此存储过程获取某些日期时间值?它甚至可能吗?
编辑:正如Adwaenyth所说,以下查询完美无缺:
DECLARE @query nvarchar(max) = 'SELECT @v_maxDate = MAX(create_date) FROM sys.tables'
DECLARE @v_maxDate datetime
EXEC sp_executesql @query, N'@v_maxDate datetime out', @v_maxDate out
PRINT @v_maxDate
我在查询中使用多个变量的事实是否可能会修改结果?
答案 0 :(得分:2)
将您的查询更改为
DECLARE @v_query as nvarchar(max) = 'SELECT @v_maxDate = MAX(DATE) FROM dbo.' + @p_Origin + ' WHERE VersionId = ' + CAST(@v_valueVersion as nvarchar) + ' AND Month = CONVERT(NVARCHAR(6),GETDATE(),112) '
它应该有用。
/ edit:只是通过这个即席查询尝试了它,它运行得很好:
DECLARE @query nvarchar(max) = 'SELECT @v_maxDate = MAX(create_date) FROM sys.tables'
DECLARE @v_maxDate datetime
EXEC sp_executesql @query, N'@v_maxDate datetime out', @v_maxDate out
PRINT @v_maxDate
完全打印输出:
2016年1月18日下午1:10
也许尝试运行上面的查询并查看它是否在您的服务器上运行......如果是,可以再次查看查询的语法。
答案 1 :(得分:0)
非常感谢您提供此信息。我遇到了同样的问题,这帮助我解决了这个问题。
这是我的理解:使用sp_executesql将查询结果分配给变量时,变量必须是查询本身的一部分。也就是说,在概念上运行步骤1({query} =“ SELECT Max(Date)FROM {table} ...”),然后在步骤2中将输出分配给变量(例如,sp_executesql {query},@ varOut OUTPUT)。最初,OP就是这样做的,这也是我最初的做法。相反,查询本身必须一步将结果分配给变量:“ SELECT @varOut = Max(Date)FROM {table} ...”
似乎第一种方法以“正常”方式运行查询(即,就像在命令行中手动键入该查询一样),因此将结果正常发送到STDOUT。如OP所见,这使Max(Date)在屏幕上可见。但是输出不会分配给变量。而是,sp_exectuesql必须具有某种成功/失败指示,默认情况下它会返回。这就是OP在打印@varOut的值时所看到的。
再次感谢您的帮助。