Ошибка арифметического переполнения при преобразовании expression к типу данных datetime

This select statement gives me the arithmetic error message:

SELECT CAST(FLOOR((CAST(LeftDate AS DECIMAL(12,5)))) AS DATETIME), LeftDate 
FROM Table
WHERE LeftDate > '2008-12-31'

While this one works:

SELECT CAST(FLOOR((CAST(LeftDate AS DECIMAL(12,5)))) AS DATETIME), LeftDate 
FROM Table
WHERE LeftDate < '2008-12-31'

Could there be something wrong with the data (I’ve checked for null values, and there are none)?

gbn's user avatar

gbn

421k81 gold badges585 silver badges674 bronze badges

asked Mar 11, 2009 at 9:24

oekstrem's user avatar

Found the problem to be when a date was set to 9999-12-31, probably to big for the decimal to handle. Changed from decimal to float, and every thing is working like a charm.

answered Mar 11, 2009 at 9:38

oekstrem's user avatar

oekstremoekstrem

4773 gold badges6 silver badges12 bronze badges

In general, converting a date to a numeric or string, to perform date operations on it, is highly inefficient. (The conversions are relatively intensive, as are string manipulations.) It is much better to stick to just date functions.

The example you give is (I believe) to strip away the time part of the DateTime, the following does that without the overhead of conversions…

DATEADD(DAY, DATEDIFF(DAY, 0, <mydate>), 0)

This should also avoid arithmentic overflows…

answered Mar 11, 2009 at 14:12

MatBailie's user avatar

MatBailieMatBailie

82.9k18 gold badges102 silver badges137 bronze badges

2

Maybe this helps someone since my problem was a bit different.

The SELECT that was throwing this error had many nested SELECTs and many date comparisons with arithmetic operations like GETDATE() - CloseDate.

The result of such operations was then being compared to '1900-01-01' again mentioned many times in the nested SELECTs.

My solution was to declare variables for result of GETDATE() and datetime variable for '1900-01-01' to avoid conversions.

Declare @CurrentDate datetime = GetDate()
Declare @BlankDate datetime = '1900-01-01'
...
... @CurrentDate - CloseDate ...
... CloseDate <> @BlankDate ...

The DATEADD(DAY, DATEDIFF(DAY, 0, <mydate>), 0) bit from MatBailie’s answer was also helpful.

answered Mar 5, 2019 at 12:21

Создал представление, содержащее следующий запрос:

SELECT TOP (100) PERCENT dbo.заявки_рас.ДатаПоступления + dbo.заявки_рас.ВремяПоступления AS datetime_add, dbo.дома.УК AS uk, 
               dbo.заявки_рас.ВидРабот AS type_work
FROM  dbo.дома INNER JOIN
               dbo.заявки_рас ON dbo.дома.АдресДома = dbo.заявки_рас.АдресДома
WHERE (dbo.заявки_рас.ОтметкаУдалить = 0) AND (dbo.заявки_рас.ЗаявкаВыполнена = 1) OR
               (dbo.заявки_рас.ОтметкаУдалить IS NULL)
ORDER BY datetime_add

И в результате получаю ошибку, упомянутую в сабже. В mssql разбираюсь плохо, подскажите где искать проблему? Индексов в таблице «заявки_рас» нету (сначала думал из за них, тк все началось после операций с пересозданием индекса).
Если убрать

dbo.заявки_рас.ДатаПоступления + dbo.заявки_рас.ВремяПоступления AS datetime_add,

…то вроде работает, но для правильного результата необходимо всетаки сложить эти два времени.

задан 16 сен 2011 в 11:02

Roman St's user avatar

0

Скорее всего, это связано с тем, что у вас колонки dbo.заявки_рас.ВремяПоступления и dbo.заявки_рас.ДатаПоступления имеют тип smalldatetime. Чтобы не было такой ошибки, нужно привести данные к типу datetime.

Но меня немного смущает метод сложения дат.

Пример. Дата 2007-05-08 12:35:00 + дата ‘2007-05-08 14:35:00 выдаст 2114-09-13 03:10:00.000, то есть складываются все составляющие дат.

Возможно, тут лучше использовать datediff метод.

Nicolas Chabanovsky's user avatar

ответ дан 16 сен 2011 в 12:46

joyecoder's user avatar

3

  • Remove From My Forums
  • Question

  • Hi All,

    The following query is giving me  this error —

    Msg 8115, Level 16, State 2, Line 5

    Arithmetic overflow error converting expression to data type datetime.

    declare

    @Year varchar(50),
    @Month
    varchar(50)

    set

    @Year =
    ‘2010’

    set

    @Month =
    ’11’

    select

    *
    from transaction_tnx

    where

    start_date_tnx = @Year+‘-‘+@Month+‘-‘+cast(
    day(start_date_tnx)
    as
    nvarchar(20))

    order

    by start_date_tnx

    For 2010 year and month 10 …only I have data….but for other years and months there is no data currently in the system….

    I am not getting why its giving me the arithemetic over flow error..?

    Any suggestions in this area…?


    vineesh1701

    • Moved by

      Tuesday, January 18, 2011 3:14 PM
      TSQL question (From:SQL Server Database Engine)

Answers

    • Proposed as answer by
      Naomi N
      Wednesday, January 19, 2011 3:58 PM
    • Marked as answer by
      KJian_
      Tuesday, January 25, 2011 8:36 AM
  • The format set by the SET DATEFORMAT instruction will apply even if you put the year in the first place; so you will get exactly the same error by using either 2010-10-31 than you will get with 10-31-2010. The following piece of code show you that the placement
    of the year change nothing if you are using the separator «-» but that if you remove the separator «-«, the SET DATEFORMAT will lose its effect:

    set dateformat dmy
    select cast ('01-02-2010' as datetime), cast ('2010-01-02' as datetime),
    cast ('20100102' as datetime)
    
    set dateformat mdy
    select cast ('01-02-2010' as datetime), cast ('2010-01-02' as datetime),
    cast ('20100102' as datetime)
    

    Sylvain Lafontaine, ing.
    MVP — Access
    Blog/web site:
    http://coding-paparazzi.sylvainlafontaine.com
    Independent consultant and remote programming for Access and SQL-Server (French)

    • Proposed as answer by
      Naomi N
      Wednesday, January 19, 2011 3:58 PM
    • Marked as answer by
      KJian_
      Tuesday, January 25, 2011 8:36 AM
  • The reason for the overflow error is that you try to build a date on the fly where the year part and month part is hardwired to November.

    November has 30 days. But in your data, you have dates for other months of 31 days such as January, March, May, July, August, October and December.

    So the on-the-fly build data is not a valid date.

    Here is how you should do.

    DECLARE @Year SMALLINT,
    	@Month TINYINT
    
    SELECT 	@Year = 2011,
    	@Month = 11
    
    DECLARE @FromDate DATETIME,
    	@ToDate = DATETIME
    
    SELECT 	@FromDate = DATEADD(MONTH, 12 * @Year - 22801 + @Month, 0),
    	@ToDate = DATEADD(MONTH, 12 * @Year - 22800 + @Month, 0)
    
    SELECT 	*
    FROM		dbo.Transaction_tnx
    WHERE		start_date_tnx >= @StartDate
    		AND start_date_tnx < @ToDate
    ORDER BY	start_date_tnx
    
    
    • Proposed as answer by
      Naomi N
      Wednesday, January 19, 2011 3:59 PM
    • Marked as answer by
      KJian_
      Tuesday, January 25, 2011 8:36 AM
  • Remove From My Forums
  • Question

  • Hi All,

    The following query is giving me  this error —

    Msg 8115, Level 16, State 2, Line 5

    Arithmetic overflow error converting expression to data type datetime.

    declare

    @Year varchar(50),
    @Month
    varchar(50)

    set

    @Year =
    ‘2010’

    set

    @Month =
    ’11’

    select

    *
    from transaction_tnx

    where

    start_date_tnx = @Year+‘-‘+@Month+‘-‘+cast(
    day(start_date_tnx)
    as
    nvarchar(20))

    order

    by start_date_tnx

    For 2010 year and month 10 …only I have data….but for other years and months there is no data currently in the system….

    I am not getting why its giving me the arithemetic over flow error..?

    Any suggestions in this area…?


    vineesh1701

    • Moved by

      Tuesday, January 18, 2011 3:14 PM
      TSQL question (From:SQL Server Database Engine)

Answers

    • Proposed as answer by
      Naomi N
      Wednesday, January 19, 2011 3:58 PM
    • Marked as answer by
      KJian_
      Tuesday, January 25, 2011 8:36 AM
  • The format set by the SET DATEFORMAT instruction will apply even if you put the year in the first place; so you will get exactly the same error by using either 2010-10-31 than you will get with 10-31-2010. The following piece of code show you that the placement
    of the year change nothing if you are using the separator «-» but that if you remove the separator «-«, the SET DATEFORMAT will lose its effect:

    set dateformat dmy
    select cast ('01-02-2010' as datetime), cast ('2010-01-02' as datetime),
    cast ('20100102' as datetime)
    
    set dateformat mdy
    select cast ('01-02-2010' as datetime), cast ('2010-01-02' as datetime),
    cast ('20100102' as datetime)
    

    Sylvain Lafontaine, ing.
    MVP — Access
    Blog/web site:
    http://coding-paparazzi.sylvainlafontaine.com
    Independent consultant and remote programming for Access and SQL-Server (French)

    • Proposed as answer by
      Naomi N
      Wednesday, January 19, 2011 3:58 PM
    • Marked as answer by
      KJian_
      Tuesday, January 25, 2011 8:36 AM
  • The reason for the overflow error is that you try to build a date on the fly where the year part and month part is hardwired to November.

    November has 30 days. But in your data, you have dates for other months of 31 days such as January, March, May, July, August, October and December.

    So the on-the-fly build data is not a valid date.

    Here is how you should do.

    DECLARE @Year SMALLINT,
    	@Month TINYINT
    
    SELECT 	@Year = 2011,
    	@Month = 11
    
    DECLARE @FromDate DATETIME,
    	@ToDate = DATETIME
    
    SELECT 	@FromDate = DATEADD(MONTH, 12 * @Year - 22801 + @Month, 0),
    	@ToDate = DATEADD(MONTH, 12 * @Year - 22800 + @Month, 0)
    
    SELECT 	*
    FROM		dbo.Transaction_tnx
    WHERE		start_date_tnx >= @StartDate
    		AND start_date_tnx < @ToDate
    ORDER BY	start_date_tnx
    
    
    • Proposed as answer by
      Naomi N
      Wednesday, January 19, 2011 3:59 PM
    • Marked as answer by
      KJian_
      Tuesday, January 25, 2011 8:36 AM

I’m getting this error

msg 8115, level 16, state 2, line 18
Arithmetic overflow error converting expression to data type int.

with this SQL query

DECLARE @year VARCHAR(4);                       
DECLARE @month VARCHAR(2);                      

-- START OF CONFIGURATION SECTION                       
-- THIS IS THE ONLY SECTION THAT SHOULD BE MODIFIED                     
-- SET THE YEAR AND MONTH PARAMETERS                        

SET @year = '2013';                     
SET @month = '3';  -- 1 = January.... 12 = Decemeber.                       

-- END OF CONFIGURATION SECTION                     

DECLARE @startDate DATE                     
DECLARE @endDate DATE                       
SET @startDate = @year + '-' + @month + '-01 00:00:00';                     
SET @endDate = DATEADD(MONTH, 1, @startDate);                       

SELECT                          
    DATEPART(YEAR, dateTimeStamp) AS [Year]                         
    , DATEPART(MONTH, dateTimeStamp) AS [Month]                         
    , COUNT(*) AS NumStreams                        
    , [platform] AS [Platform]                      
    , deliverableName AS [Deliverable Name]                     
    , SUM(billableDuration) AS NumSecondsDelivered                      
FROM                            
    DeliveryTransactions                        
WHERE                           
    dateTimeStamp >= @startDate                     
AND dateTimeStamp < @endDate                        
GROUP BY                            
    DATEPART(YEAR, dateTimeStamp)                       
    , DATEPART(MONTH, dateTimeStamp)                        
    , [platform]                        
    , deliverableName                       
ORDER BY                            
    [platform]                      
    , DATEPART(YEAR, dateTimeStamp)                         
    , DATEPART(MONTH, dateTimeStamp)                        
    , deliverableName   

Вопрос:

При выполнении следующей ошибки отображается

declare @yr_mnth_dt as numeric;
set @yr_mnth_dt = 20130822;
select convert(datetime,@yr_mnth_dt,112) as YR_MNTH_DT

ошибка показывает

Arithmetic overflow error converting expression to data type datetime.

Лучший ответ:

Вы указываете, что вы пытаетесь convert использовать числовое значение , и это просто не работает.

Вам нужно сначала превратить ваш numeric в строку:

declare @yr_mnth_dt as numeric;
set @yr_mnth_dt = 20130822;

select yr_mnth_dt = cast(cast(@yr_mnth_dt as char(8)) as datetime);

SQL Fiddle с демонстрацией.

Когда вы пытаетесь преобразовать числовой тип в datetime, SQL Server пытается добавить числовое значение как число дней до даты 01-Jan-1900. В вашем случае это пытается добавить миллионы дней и, следовательно, ошибку переполнения.

convert отлично работает, если вы предпочитаете:

select yr_mnth_dt = convert(datetime, convert(char(8), @yr_mnth_dt));

SQL Fiddle с демонстрацией.

Ответ №1

Я видел только преобразование, используемое для строк. Я не могу легко сказать, даже он предназначен для работы с числами. Вы можете преобразовать число в строку, а затем строку в дату. Однако я бы просто использовал DATEFROMPARTS:

SELECT DATEFROMPARTS(@yr_mnth_dt / 10000,
(@yr_mnth_dt / 100) % 100,
@yr_mnth_dt % 100) AS YR_MNTH_DT

Ответ №2

Почему числовое?
Попробуйте это

declare @yr_mnth_dt as varchar(10);
set @yr_mnth_dt = '20130822';
select convert(datetime,@yr_mnth_dt,112) as YR_MNTH_DT

SQL Server 2012 Developer SQL Server 2012 Enterprise SQL Server 2012 Standard Еще…Меньше

Проблемы

Рассмотрим следующий сценарий.

  • Вы создаете связанный сервер для Microsoft SQL Server 2012.

  • При попытке выполнить инструкцию SQL, вызывающую системную хранимую процедуру sys.sp_tables_info_90_rowset_64 , чтобы получить доступ к таблице из экземпляра SQL Server 2012 по умолчанию.

  • Таблица содержит более 2 500 000 000 записей.

В этом случае появляется следующее сообщение об ошибке:

Сообщение 8115, уровень 16, состояние 2, sp_tables_info_90_rowset_64 процедуры, строка 9Arithmetic ошибка переполнения при преобразовании выражения в тип данных int.

Примечание.Эта проблема возникает при настройке SQL Server 2012 в качестве целевого сервера.

Решение

Сведения о накопительном пакете обновления

Накопительный пакет обновления 1 (SP1) для SQL Server 2012 с пакетом обновления 1 (SP1)

Исправление для этой проблемы впервые выпущено в накопительном обновлении 1. За дополнительными сведениями о том, как получить этот накопительный пакет обновления для SQL Server 2012 с пакетом обновления 1 (SP1), щелкните следующий номер статьи базы знаний Майкрософт:

2765331 Накопительный пакет обновления 1 (SP1) для SQL Server 2012 с пакетом обновления 1 (SP1)Примечание. Так как сборки являются кумулятивными, каждый новый выпуск исправлений содержит все исправления и все исправления безопасности, которые были включены в предыдущий выпуск исправлений для SQL Server 2012. Рекомендуется установить последнюю версию исправления, которая включает это исправление. Дополнительные сведения см. в следующей статье базы знаний Майкрософт:

2772858 Сборки SQL Server 2012, выпущенные после выпуска пакета обновления 1 (SP1) для SQL Server 2012

SQL Server 2012

Исправление для этой проблемы впервые выпущено в накопительном обновлении 4. Для получения дополнительных сведений о том, как получить этот накопительный пакет обновления для SQL Server 2012, щелкните следующий номер статьи базы знаний Майкрософт:

2758687 Накопительный пакет обновления 4 для SQL Server 2012Примечание. Так как сборки являются кумулятивными, каждый новый выпуск исправлений содержит все исправления и все исправления безопасности, которые были включены в предыдущий выпуск исправлений для SQL Server 2012. Рекомендуется установить последнюю версию исправления, которая включает это исправление. Дополнительные сведения см. в следующей статье базы знаний Майкрософт:

2692828 Сборки SQL Server 2012, выпущенные после выпуска SQL Server 2012

Статус

Корпорация Майкрософт подтверждает наличие этой проблемы в своих продуктах, которые перечислены в разделе «Применяется к».

Дополнительная информация

Дополнительные сведения о том, как настроить связанные серверы в SQL Server 2012, можно найти на веб-сайте MSDN по следующему адресу:

Настройка связанных серверов в SQL Server 2012

Нужна дополнительная помощь?

Я получаю данные из представления, и один из столбцов, которые я использую, — nvarchar(50), но всегда только N'True' или N'False', в зависимости от работы связанного столбца даты в этом родительском представлении.

Следующий код извлекает идентификатор записи и столбец, который я ищу, YTD:

SELECT Enquiry_Number, YTD 
FROM dbo.vw_SalesPO_YTD

Выход:

ENQ-001 True
ENQ-002 False
ENQ-003 True

Однако по какой-то причине я не могу фильтровать свои результаты с помощью этого столбца YTD. Если я попытаюсь сделать это:

SELECT Enquiry_Number, YTD
FROM dbo.vw_SalesPO_YTD
WHERE YTD = N'True'

Затем происходит сбой со следующей ошибкой:

Ошибка арифметического переполнения при преобразовании выражения в тип данных datetime.

Этого я не понимаю, потому что в этом запросе нет выражений datetime. Да, True или False были определены путем сравнения дат и времени в родительском представлении, но я не понимаю, как это могло попасть в этот подзапрос. Попытка сделать то же самое в родительском представлении дает ту же ошибку — я демонстрирую это таким образом для простоты.

Однако выполнение аналогичной операции в части запроса SELECT работает без проблем:

SELECT 
    Enquiry_Number,
    YTD,
    CASE 
       WHEN YTD = N'True' THEN 1 ELSE 0 
    END As C
FROM
    dbo.vw_SalesPO_YTD 

Выход:

ENQ-001 True 1
ENQ-002 False 0
ENQ-003 True 1

Однако эти 1 и 0 наследуют один и тот же недостаток, поэтому я не могу использовать их в предложении WHERE без этой ошибки datetime.

Я много искал и не знаю, как определить основную проблему. Я читал кое-что о сопоставлениях и приоритетах типов, но не могу понять, почему происходит такое поведение.

Когда я проверил YTD в INFORMATION_SCHEMA.COLUMNS, это подтверждает, что этот столбец ничем не отличается от других столбцов в моей таблице: YTD равен nvarchar(50), используя {{X4} } сопоставление.

Связанный вопрос: Выражение преобразования ошибки арифметического переполнения SQL Server к типу данных datetime


Источник проблемы

Эта проблема все еще не решена, но если вы хотите воспроизвести ее, этот код из родительского представления должен генерировать эту проблему:

CASE WHEN 
Award_Date <= DATEFROMPARTS(FinancialYear - 1, 11, 1) + GETDATE() - DATEADD(year, DATEDIFF(month, '20161101', GETDATE()) / 12, '20161101')
THEN N'True'
ELSE N'False'
END

Да, это выглядит слишком сложно. Мы сравниваем Award_Date с связанным FinancialYear, который длится с 1 ноября по 31 октября. Каждая запись уже знает, в каком FinancialYear она находится. Конечная цель состоит в том, чтобы сравнить позицию СЕГОДНЯ (30.11.2016) с СЕГОДНЯМИ в прошлом году (2015-11-30) и СЕГОДНЯ годом ранее (2014-11- 30) и др.

Таким образом, код берет сегодняшнюю дату и объединяет ее с FinancialYear для связанной записи и показывает, произошла ли запись между началом финансового года и сегодня того же года. . И он делает это успешно, но тогда я ничего не могу сделать с N'True' или N'False', которые он производит.

5 ответов

Лучший ответ

Это успешный обходной путь , а не решение как таковое или объяснение основной проблемы.

Очевидно, что существует проблема с данными, поступающими из представления, которая не позволяет обрабатывать результаты столбца YTD в предложении WHERE, и тем не менее, они могут быть обработаны к тому времени, когда запрос достигнет его SELECT фаза.

Я создал новый table, который явно определяет столбец YTD как nvarchar(50), а затем вставил все записи из моего представления в эту таблицу, что устранило проблему. Затем записи можно отсортировать и отфильтровать по YTD, как и положено.


0

Steve Taylor
30 Ноя 2016 в 14:02

SELECT *
FROM (SELECT Enquiry_Number, YTD
FROM dbo.vw_SalesPO_YTD) AS A
WHERE cast(A.YTD as varchar) = 'True'


1

Krish
30 Ноя 2016 в 12:45

В качестве примера я использовал следующее:

DECLARE @Data TABLE
(
    Enquiry_Number nvarchar(10),
    YTD nvarchar(50)
)

INSERT INTO @Data(Enquiry_Number, YTD)
SELECT N'ENQ-001', N'True' UNION
SELECT N'ENQ-002', N'False' UNION
SELECT N'ENQ-003', N'True' 


SELECT Enquiry_Number, [YTD] FROM (
    SELECT Enquiry_Number, CONVERT(nvarchar(10),YTD) AS [YTD] FROM @Data
) AS A
WHERE A.YTD = N'True'

Результат:

ENQ-001 True
ENQ-003 True

В поле YTD должны быть результаты, которые заставят его вернуть как тип datetime.

Попробуйте такой запрос:

SELECT * FROM dbo.vw_SalesPO_YTD WHERE ISDATE(YTD)= 1

Обновленный вопрос: попробуйте:

ISNULL(CASE WHEN  Award_Date <= DATEFROMPARTS(FinancialYear - 1, 11, 1) + GETDATE() - DATEADD(year, DATEDIFF(month, '20161101', GETDATE()) / 12, '20161101') THEN N'True' ELSE N'False' END, 'false')


1

Danie Schoeman
30 Ноя 2016 в 13:38

Попробуйте это: — Не добавляйте n перед строкой

SELECT *
FROM (SELECT Enquiry_Number, YTD
FROM dbo.vw_SalesPO_YTD) AS A
WHERE A.YTD = 'True'


1

frhd
30 Ноя 2016 в 14:21

Я не знаю, что это за тип источника с начала года.

Попробуйте использовать следующее:

SELECT Enquiry_Number, [YTD] FROM (
    SELECT Enquiry_Number, CONVERT(nvarchar(10),YTD) AS [YTD] FROM dbo.vw_SalesPO_YTD
) AS A
WHERE A.YTD = N'True'

10 — это просто отстойное значение. Он будет вырезать любую часть поля длиной более 10. Это зависит от вашего фактического размера поля.


1

Danie Schoeman
30 Ноя 2016 в 12:35

This select statement gives me the arithmetic error message:

SELECT CAST(FLOOR((CAST(LeftDate AS DECIMAL(12,5)))) AS DATETIME), LeftDate 
FROM Table
WHERE LeftDate > '2008-12-31'

While this one works:

SELECT CAST(FLOOR((CAST(LeftDate AS DECIMAL(12,5)))) AS DATETIME), LeftDate 
FROM Table
WHERE LeftDate < '2008-12-31'

Could there be something wrong with the data (I’ve checked for null values, and there are none)?

gbn's user avatar

gbn

417k81 gold badges581 silver badges670 bronze badges

asked Mar 11, 2009 at 9:24

oekstrem's user avatar

Found the problem to be when a date was set to 9999-12-31, probably to big for the decimal to handle. Changed from decimal to float, and every thing is working like a charm.

answered Mar 11, 2009 at 9:38

oekstrem's user avatar

oekstremoekstrem

4773 gold badges6 silver badges12 bronze badges

In general, converting a date to a numeric or string, to perform date operations on it, is highly inefficient. (The conversions are relatively intensive, as are string manipulations.) It is much better to stick to just date functions.

The example you give is (I believe) to strip away the time part of the DateTime, the following does that without the overhead of conversions…

DATEADD(DAY, DATEDIFF(DAY, 0, <mydate>), 0)

This should also avoid arithmentic overflows…

answered Mar 11, 2009 at 14:12

MatBailie's user avatar

MatBailieMatBailie

81.3k18 gold badges101 silver badges137 bronze badges

2

Maybe this helps someone since my problem was a bit different.

The SELECT that was throwing this error had many nested SELECTs and many date comparisons with arithmetic operations like GETDATE() - CloseDate.

The result of such operations was then being compared to '1900-01-01' again mentioned many times in the nested SELECTs.

My solution was to declare variables for result of GETDATE() and datetime variable for '1900-01-01' to avoid conversions.

Declare @CurrentDate datetime = GetDate()
Declare @BlankDate datetime = '1900-01-01'
...
... @CurrentDate - CloseDate ...
... CloseDate <> @BlankDate ...

The DATEADD(DAY, DATEDIFF(DAY, 0, <mydate>), 0) bit from MatBailie’s answer was also helpful.

answered Mar 5, 2019 at 12:21

This select statement gives me the arithmetic error message:

SELECT CAST(FLOOR((CAST(LeftDate AS DECIMAL(12,5)))) AS DATETIME), LeftDate 
FROM Table
WHERE LeftDate > '2008-12-31'

While this one works:

SELECT CAST(FLOOR((CAST(LeftDate AS DECIMAL(12,5)))) AS DATETIME), LeftDate 
FROM Table
WHERE LeftDate < '2008-12-31'

Could there be something wrong with the data (I’ve checked for null values, and there are none)?

gbn's user avatar

gbn

417k81 gold badges581 silver badges670 bronze badges

asked Mar 11, 2009 at 9:24

oekstrem's user avatar

Found the problem to be when a date was set to 9999-12-31, probably to big for the decimal to handle. Changed from decimal to float, and every thing is working like a charm.

answered Mar 11, 2009 at 9:38

oekstrem's user avatar

oekstremoekstrem

4773 gold badges6 silver badges12 bronze badges

In general, converting a date to a numeric or string, to perform date operations on it, is highly inefficient. (The conversions are relatively intensive, as are string manipulations.) It is much better to stick to just date functions.

The example you give is (I believe) to strip away the time part of the DateTime, the following does that without the overhead of conversions…

DATEADD(DAY, DATEDIFF(DAY, 0, <mydate>), 0)

This should also avoid arithmentic overflows…

answered Mar 11, 2009 at 14:12

MatBailie's user avatar

MatBailieMatBailie

81.3k18 gold badges101 silver badges137 bronze badges

2

Maybe this helps someone since my problem was a bit different.

The SELECT that was throwing this error had many nested SELECTs and many date comparisons with arithmetic operations like GETDATE() - CloseDate.

The result of such operations was then being compared to '1900-01-01' again mentioned many times in the nested SELECTs.

My solution was to declare variables for result of GETDATE() and datetime variable for '1900-01-01' to avoid conversions.

Declare @CurrentDate datetime = GetDate()
Declare @BlankDate datetime = '1900-01-01'
...
... @CurrentDate - CloseDate ...
... CloseDate <> @BlankDate ...

The DATEADD(DAY, DATEDIFF(DAY, 0, <mydate>), 0) bit from MatBailie’s answer was also helpful.

answered Mar 5, 2019 at 12:21

#sql #tsql #jdbc

#sql #tsql #jdbc

Вопрос:

Я пытаюсь выполнить этот простой запрос, чтобы получить сумму всех сумм за прошлый год и получить ошибку. Может кто-нибудь пролить свет на это, пожалуйста. Я не выполняю никакого приведения, а столбец TX_DATE имеет тип date.

 SELECT SUM(AMOUNT) as TOTAL
FROM
    TRANSACTIONS
WHERE
    ID = '12345'
    AND TYPE = 'Amount'
    AND DATEDIFF(MONTH,TX_DATE,GETDATE()) <= 12
  

Ошибка:

 Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Arithmetic overflow error converting expression to data type datetime.
    at   com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet$FetchBuffer.nextRow(SQLServerResultSet.java:4853)
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.fetchBufferNext(SQLServerResultSet.java:1781)
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.next(SQLServerResultSet.java:1034)
    at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)
    at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:91)
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:1)
    at org.springframework.jdbc.core.JdbcTemplate$1QueryStatementCallback.doInStatement(JdbcTemplate.java:446)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:396)
    ... 50 more
  

Комментарии:

1. Может ли TX_DATE быть типом поля, отличным от DATE или DATETIME?

2. ДА. Действительно. Его nvarchar в UAT env и Date в моем собственном evn 😉

3. Кажется, он содержит мусорные даты, тогда … 🙂

4. Поскольку вы используете Datediff для datepart month, вероятность возврата значения, которое находится вне диапазона для int, сомнительна. Это единственный запрос, который запускается, или это часть какого-то большого запроса. Также узнайте максимальные и минимальные даты TX_DATE из таблицы ТРАНЗАКЦИЙ. Может быть, это помогает.

Ответ №1:

Проверьте тип TX_DATE . Кажется, это не дата.

Комментарии:

1. Действительно, TX_DATE не имеет типа date (проверено после того, как я опубликовал вопрос). То, что мне до сих пор не ясно, заключается в том, почему запрос не завершается с ошибкой при запуске через Microsoft SQL Server Management Studio, но завершается с ошибкой при запуске через jdbc.

2. Это две разные системы, поэтому все зависит от того, как было интерпретировано значение TX_DATE .

Обновлено 16.11.2019

Вопрос:

При выполнении следующей ошибки отображается

declare @yr_mnth_dt as numeric;
set @yr_mnth_dt = 20130822;
select convert(datetime,@yr_mnth_dt,112) as YR_MNTH_DT

ошибка показывает

Arithmetic overflow error converting expression to data type datetime.

Лучший ответ:

Вы указываете, что вы пытаетесь convert использовать числовое значение , и это просто не работает.

Вам нужно сначала превратить ваш numeric в строку:

declare @yr_mnth_dt as numeric;
set @yr_mnth_dt = 20130822;

select yr_mnth_dt = cast(cast(@yr_mnth_dt as char(8)) as datetime);

SQL Fiddle с демонстрацией.

Когда вы пытаетесь преобразовать числовой тип в datetime, SQL Server пытается добавить числовое значение как число дней до даты 01-Jan-1900. В вашем случае это пытается добавить миллионы дней и, следовательно, ошибку переполнения.

convert отлично работает, если вы предпочитаете:

select yr_mnth_dt = convert(datetime, convert(char(8), @yr_mnth_dt));

SQL Fiddle с демонстрацией.

Ответ №1

Я видел только преобразование, используемое для строк. Я не могу легко сказать, даже он предназначен для работы с числами. Вы можете преобразовать число в строку, а затем строку в дату. Однако я бы просто использовал DATEFROMPARTS:

SELECT DATEFROMPARTS(@yr_mnth_dt / 10000,
(@yr_mnth_dt / 100) % 100,
@yr_mnth_dt % 100) AS YR_MNTH_DT

Ответ №2

Почему числовое?
Попробуйте это

declare @yr_mnth_dt as varchar(10);
set @yr_mnth_dt = '20130822';
select convert(datetime,@yr_mnth_dt,112) as YR_MNTH_DT

  • Ошибка аристон духовой шкаф f5e2
  • Ошибка аристон sp1 на котле что значит
  • Ошибка ардуино programmer is not responding
  • Ошибка ардуино else without a previous if
  • Ошибка апс не отвечает приора