T-SQL错误:将值添加到' smalldatetime'列导致溢出。 SQL服务器错误?

时间:2015-11-24 12:46:40

标签: sql-server tsql

当我尝试执行以下代码时,我收到错误"将值添加到' smalldatetime'列导致溢出":

DECLARE @t TABLE (ID UNIQUEIDENTIFIER, BegDate SMALLDATETIME, EndDate SMALLDATETIME)

INSERT INTO @t
SELECT NEWID(), '19000101', '20151124'

-- This is to show you that nothing is really selected
SELECT 'You will never see it'
FROM @t r1
INNER JOIN @t r2 ON r2.ID = r1.ID
WHERE   1=1
    AND r1.BegDate > r2.BegDate    
    AND r1.EndDate <= r2.EndDate

SELECT r1.ID, r2.BegDate, DATEADD(DAY, -1, r1.BegDate) AS EndDate
FROM @t r1
INNER JOIN @t r2 ON r2.ID = r1.ID
WHERE   1=1
    AND r1.BegDate > r2.BegDate  -- This guarantees that r1.BegDate is not minimal value
    AND r1.EndDate <= r2.EndDate

如您所见,DATEADD()的结果不能小于最小值。而且,不能调用DATEADD(),因为SELECT必须不返回任何内容。 它是SQL服务器的错误吗?

2 个答案:

答案 0 :(得分:5)

smalldatetime值具有以下日期范围:

  

1900-01-01至2079-06-06

     

1900年1月1日至2079年6月6日

您收到错误是因为您的计算导致日期超出此界限:

DECLARE  @BegDate SMALLDATETIME = '19000101'
SELECT @BegDate
SELECT DATEADD(DAY, -1, @BegDate)

问题是SELECT内容在FROMJOINWHERE之前执行的原因,因为这不是Logical Processing Order of the SELECT statement

如果将19000101值更改为19000102,只是为了获得SQL引擎正在构建的执行计划,您应该看到:

enter image description here

Compute Scalar实际上是DATEADD函数执行:

enter image description here

因此,执行DATEADD函数并抛出错误。这是因为:

  

请注意,确定语句的实际物理执行   由查询处理器和订单可能会有所不同。

SELECT r1.ID, r2.BegDate, IIF(r1.BegDate = '19000101', NULL, DATEADD(DAY, -1, r1.BegDate)) AS EndDate
FROM @t r1
INNER JOIN @t r2 ON r2.ID = r1.ID
WHERE   1=1
    AND r1.BegDate > r2.BegDate  -- This guarantees that r1.BegDate is not minimal value
    AND r1.EndDate <= r2.EndDate

您可以使用OPTION(FORCE ORDER)更改执行计划并使查询正常工作:

SELECT r1.ID, r2.BegDate, DATEADD(DAY, -1, r1.BegDate) AS EndDate
FROM @t r1 
INNER JOIN @t r2 ON r2.ID = r1.ID
WHERE   1=1
    AND r1.BegDate > r2.BegDate  -- This guarantees that r1.BegDate is not minimal value
    AND r1.EndDate <= r2.EndDate
OPTION  (FORCE ORDER)

enter image description here

答案 1 :(得分:1)

我在这里收到了答案:

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/1a60b3a1-0e18-41aa-b40a-bc64558f6ce2/tsql-error-adding-a-value-to-a-smalldatetime-column-caused-overflow-sql-server-bug?forum=transactsql&prof=required

在这种情况下,我可以使用OPTION(FORCE ORDER):

SELECT r1.ID, r2.BegDate, DATEADD(DAY, -1, r1.BegDate) AS EndDate
FROM @t r1
INNER JOIN @t r2 ON r2.ID = r1.ID
WHERE   1=1
    AND r1.BegDate > r2.BegDate  -- This guarantees that r1.BegDate is not minimal value
    AND r1.EndDate <= r2.EndDate
OPTION(FORCE ORDER)