为查询字符串声明变量

时间:2010-09-30 17:50:19

标签: sql sql-server sql-server-2005 tsql dynamic-sql

我想知道在MS SQL Server 2005中是否有办法做到这一点:

  DECLARE @theDate varchar(60)
  SET @theDate = '''2010-01-01'' AND ''2010-08-31 23:59:59'''

  SELECT    AdministratorCode, 
            SUM(Total) as theTotal, 
            SUM(WOD.Quantity) as theQty, 
            AVG(Total) as avgTotal, 
            (SELECT SUM(tblWOD.Amount)
                FROM tblWOD
                JOIN tblWO on tblWOD.OrderID = tblWO.ID
                WHERE tblWO.Approved = '1' 
                AND tblWO.AdministratorCode = tblWO.AdministratorCode
                AND tblWO.OrderDate BETWEEN @theDate
            )
 ... etc

这可能吗?

4 个答案:

答案 0 :(得分:81)

这是可能的,但它需要使用动态SQL 我建议在继续阅读之前阅读The curse and blessings of dynamic SQL

DECLARE @theDate varchar(60)
SET @theDate = '''2010-01-01'' AND ''2010-08-31 23:59:59'''

DECLARE @SQL VARCHAR(MAX)  
SET @SQL = 'SELECT AdministratorCode, 
                   SUM(Total) as theTotal, 
                   SUM(WOD.Quantity) as theQty, 
                   AVG(Total) as avgTotal, 
                  (SELECT SUM(tblWOD.Amount)
                     FROM tblWOD
                     JOIN tblWO on tblWOD.OrderID = tblWO.ID
                    WHERE tblWO.Approved = ''1''
                      AND tblWO.AdministratorCode = tblWO.AdministratorCode
                      AND tblWO.OrderDate BETWEEN '+ @theDate +')'

EXEC(@SQL)

动态SQL只是一个SQL语句,在执行之前由字符串组成。因此通常会发生字符串连接。只要您想要在SQL语法中执行某些不允许的操作,就需要动态SQL,例如:

  • 用于表示IN子句的逗号分隔值列表的单个参数
  • 表示值和SQL语法的变量(IE:您提供的示例)

EXEC sp_executesql允许您使用bind / preparedstatement参数,因此您不必担心使用SQL注入攻击转义单引号/ etc。

答案 1 :(得分:49)

DECLARE @theDate DATETIME
SET @theDate = '2010-01-01'

然后更改您的查询以使用此逻辑:

AND 
(
    tblWO.OrderDate > DATEADD(MILLISECOND, -1, @theDate) 
    AND tblWO.OrderDate < DATEADD(DAY, 1, @theDate)
)

答案 2 :(得分:2)

使用EXEC

您可以使用以下示例构建SQL语句。

DECLARE @sqlCommand varchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city varchar(75)
SET @columnList = 'CustomerID, ContactName, City'
SET @city = '''London'''
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM customers WHERE City = ' + @city
EXEC (@sqlCommand)

使用sp_executesql

使用此方法可以确保传递给查询的数据值是正确的数据类型,并避免使用更多引号。

DECLARE @sqlCommand nvarchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city varchar(75)
SET @columnList = 'CustomerID, ContactName, City'
SET @city = 'London'
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM customers WHERE City = @city'
EXECUTE sp_executesql @sqlCommand, N'@city nvarchar(75)', @city = @city

Reference

答案 3 :(得分:1)

我将指出,在最受好评的答案The Curse and Blessings of Dynamic SQL中链接的文章中,作者声明答案不是使用动态SQL。滚动几乎到最后看到这个。

来自文章:&#34;正确的方法是将列表解压缩到具有用户定义函数或存储过程的表中。&#34;

当然,一旦列表在表格中,您就可以使用联接。我无法直接对评分最高的答案发表评论,所以我只是添加了这条评论。