从变量运行查询时如何在SQL中表达BETWEEN语句

时间:2015-09-03 10:51:29

标签: sql sql-server

我有一个相当大的声明,我使用@SQL变量构建,然后从语句末尾的变量运行查询。除了在其中一个参数中插入日期之外,这种方法很好。

然后查询不返回任何数据并返回错误:

  

从字符串转换日期和/或时间时转换失败。

我目前拥有的SQL如下:

setlocal ENABLEDELAYEDEXPANSION
set /a incvar = 1
set outfvar = "outfile"_!incvar!".res"
echo !outfvar!
echo *.txt > !outfvar!
set /a incvar = incvar+1

FOR %%pat in (%*) do(
    FOR /F %%k in (!outfvar!) DO( grep -l !pat! !k! >>outfile_!incvar!.res)
    set /a incvar = incvar+1
    set outfvar = "outfile"_!incvar!.res
                     )

我知道这个问题存在于这个领域:

it("should update code when the key is changed through selector", function () {
      var Code = "123";
      var expectedCode;

      service.updateCode(Code).then(function (expectedCode) {
        expectedCode = expectedCode;
      });

      // promises are resolved/dispatched only on next $digest cycle
      $rootScope.$apply(); 
      expect(expectedCode).toEqual(`enter code here`Code);
    });

但我不确定如何解决它 - 有人能说出我可能做错了吗?

4 个答案:

答案 0 :(得分:3)

已经指出@SessionStartedVARCHAR,应该是约会。并且您的最终SQL格式错误,并且不再有效:

DECLARE @p3 DATE = GETDATE();
SELECT Test = @p3 '23:59:59';

给出了:

  

Msg 102,Level 15,State 1,Line 3

     

'23:59:59'附近的语法不正确。

但我想强调另一点:

请勿在此类之间使用

您正在尝试构建如下语句:

WHERE Date BETWEEN '2015-09-03'  AND '2015-09-03 23:59:59'

但如果Date是'2015-09-03 23:59:59.5',那么你真的希望将其排除在外吗?最佳做法是使用开放式范围:

WHERE Date >= '2015-09-03'
AND Date < '2015-09-04'

几乎相同,但涵盖了整整一天,而不仅仅是大部分时间。所以你的确切陈述应该是:

IF NULLIF(@SessionStarted, '01/01/1900') IS NOT NULL 
    SET @SQL += N' AND VisitDate >= @p3 AND VisitDate < DATEADD(DAY, 1, @p3)';

Aaron Bertrand写了great article进一步阅读。

总而言之,部分解决方法是使用concatenatation运算符+

DECLARE @p3 VARCHAR(50) = '03/09/2015';
SELECT Test = @p3 + ' 23:59:59';

更好的解决方法是转换为正确的数据类型:

DECLARE @p3 VARCHAR(50) = '03/09/2015';
SELECT Test = CONVERT(DATETIME, @p3 + ' 23:59:59');

更好的方法是使用文化不变的日期格式,因此很清楚您是指9月3日还是3月9日:

DECLARE @p3 VARCHAR(50) = '20150903';
SELECT Test = CONVERT(DATETIME, @p3 + ' 23:59:59');

更好的方法是首先使用正确的数据类型:

DECLARE @p3 DATETIME = '20150903';
SELECT Test = @p3 + '23:59:59';

更好的是,将使用如上所述的开放日期范围。

答案 1 :(得分:1)

您已将sessionstarted声明为字符而非日期。我想这是你问题的根本原因。

将类型更改为日期。我还建议您使用ISO标准YYYY-MM-DD格式作为日期,而不是特定于文化的格式。

答案 2 :(得分:0)

你的问题就在于此     @ p3 23:59:59';

您正在尝试将字符串值连接到日期。您需要做的是添加(DATEADD)到@ p3中保存的日期,并将其用作另一个参数

答案 3 :(得分:0)

首先,您需要使用正确的数据类型。在您的情况下,@SessionStarted应声明为DATE,而不是VARCHAR

执行此操作后,不应将23:59:59添加到日期字段以获取当天发生的记录,而应使用此代码:

SET @SQL += N' AND VisitDate >= @p3 AND VisitDate < DATEADD(DAY, -1, @p3)'