在SQL查询中以字符串格式传递Datetime?

时间:2011-05-17 21:52:08

标签: sql sql-server tsql

我有字符串查询并将@Date对象传递给字符串。它给出了错误。见下面的代码。

Declare @MidDate datetime, @MaxDate datetime


set @qrysales_trans_unit_26wks ='update historical_result
    set sales_trans_unit_26wks = (      
            SELECT      
            SUM(sales_trans_unit)
            FROM reg_summary_rowno  WHERE  
            period_idx >= '+  @MidDate  // error 
            +' AND period_idx <'+  @MaxDate /error
            +' AND Client_id ='+ @Client_id
            +' and historical_result.[store_idx] = reg_summary_rowno.[store_idx]
            And [attributes] ='+  @attributes +')'

如何以正确的方式将Datetime对象传递给字符串Query?

7 个答案:

答案 0 :(得分:2)

尝试使用两个单引号来转义引号,以便日期最终如下:period_idx&gt; ='@ MidDate'

set @qrysales_trans_unit_26wks ='update historical_result
        set sales_trans_unit_26wks = (      
                SELECT      
                SUM(sales_trans_unit)
                FROM reg_summary_rowno  WHERE  
                period_idx >= '''+  @MidDate
                +''' AND period_idx <'''+  @MaxDate
                +''' AND Client_id ='+ @Client_id
                +' and historical_result.[store_idx] = reg_summary_rowno.[store_idx]
                And [attributes] ='+  @attributes +')'

单击here以获取有关在SQL中转义引号的更多信息。

答案 1 :(得分:2)

有两个更好的选择,恕我直言。

如果您真的想使用动态SQL,请阅读sp_executesql - 并使用将参数传递给SQL的功能。您将以这种方式防止SQL注入攻击,并且还将避免遇到必须使用string-ify参数值的问题。

否则,使用存储过程 - 我认为这是更好的选择。

答案 2 :(得分:0)

您可以使用smaltimeatetime而不是datetime 你可以使用这样的日期:

Declare @MidDate smalldatetime,
set @MidDate = '20110317'

希望它有所帮助。

答案 3 :(得分:0)

要修复错误,您需要在字符串中的日期周围添加一些单引号'

还有一件可以提高清晰度的事情。使用BETWEEN关键字:

    WHERE period_idx BETWEEN @MinimumDate AND @MaximumDate

答案 4 :(得分:0)

如果您必须以字符串格式传递日期 - 首先,将其放在引号中,其次,我强烈建议您使用标准的ISO-8601日期格式(YYYYMMDD或{{ 1}})。

这些ISO标准格式的最大好处是无论SQL Server设置的语言和区域设置如何,它们都能正常工作。任何其他字符串表示都依赖于语言,例如

YYYY-MM-DDTHH:MM:SS

意味着:

  • 2010年5月10日在美国
  • 2010年10月5日,几乎所有世界其他地方

但是05/10/2010 很清楚且从不含糊 - 它始终是2010年10月5日 - 即使是在美国: - )

答案 5 :(得分:0)

我认为你应该在将日期变量与句子

连接之前使用convert
Declare @MidDate datetime, @MaxDate datetime
set @qrysales_trans_unit_26wks = 'update historical_result
     set sales_trans_unit_26wks = (      
            SELECT      
            SUM(sales_trans_unit)
            FROM reg_summary_rowno  
            WHERE  
            period_idx >= '+ '''' + convert(varchar, @MidDate, 112) + ''''  // error 
            +' AND period_idx <'+  '''' + convert(varchar, @MaxDate, 112) + '''' /error
            +' AND Client_id ='+ @Client_id
            +' and historical_result.[store_idx] = reg_summary_rowno.[store_idx]
            And [attributes] ='+  @attributes +')'

答案 6 :(得分:-1)

我真的建议你不要以这种方式连接SQL。它会真正打开你注射攻击等。

请查看此示例,了解您可能采取的另一种方法。

use tempdb
create table foo (id int not null identity, data datetime)

insert foo(data) values
('1/1/2010'),('1/10/2010'),('3/31/2010')


Declare @SQLStr nvarchar(4000)

set @SQLStr = 'select * from foo where data = @Data'

exec sp_executeSQL @SQLStr, N'@Data datetime', '1/1/2010'