为查询字符串声明变量

Ste*_*hRT 86 sql t-sql sql-server sql-server-2005 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
Run Code Online (Sandbox Code Playgroud)

这可能吗?

OMG*_*ies 86

这是可能的,但它需要使用动态SQL.
我建议在继续之前阅读动态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)
Run Code Online (Sandbox Code Playgroud)

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

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

EXEC sp_executesql 允许您使用bind/preparedstatement参数,这样您就不必担心SQL注入攻击会转义单引号/ etc.


hun*_*ter 50

DECLARE @theDate DATETIME
SET @theDate = '2010-01-01'
Run Code Online (Sandbox Code Playgroud)

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

AND 
(
    tblWO.OrderDate > DATEADD(MILLISECOND, -1, @theDate) 
    AND tblWO.OrderDate < DATEADD(DAY, 1, @theDate)
)
Run Code Online (Sandbox Code Playgroud)

  • 不挂断.如果问题清楚地表明两个不同的日期,那就不是答案.你最近是如何编写它@StealthRT的?答案中的"2010-08-31"日期在哪里?此外,问题清楚地询问您是否可以使用DECLARE变量将代码替换为另一个SELECT语句.正确答案如下. (2认同)

Som*_*luk 5

使用执行

您可以使用以下示例来构建 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)
Run Code Online (Sandbox Code Playgroud)

使用 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
Run Code Online (Sandbox Code Playgroud)

参考