Арифметическое переполнение MS SQL после сравнения даты и времени в предложении where - PullRequest
0 голосов
/ 10 января 2019

У меня странная проблема с использованием сравнения дат на MS SQL Server 2014.

SELECT * FROM (SELECT AKTDET.*, DATEDIFF(day,aktdet.Bezahlt_am, getdate()- 50) as datumsdifferenz FROM (SELECT  Convert(datetime,AKTDET.von_num - 2.0,121) as [Bezahlt_am], AKT.KENNUNG, AKTDET.* FROM AKT INNER JOIN AKTDET ON AKT.DSN = AKTDET.AKT_DSN Inner JOin FLDART ON AKTDET.Fldart_Dsn = FLDART.DSN WHERE FLDART.Kürzel = 'bezahlt am') AS AKTDET ) AS AKTDET WHERE datumsdifferenz > 0.0

каждый раз терпит неудачу с «Arithmetischer Überlauffehler beim Konvertieren von expression в den datetime-Datentyp». перевод: «Ошибка арифметического переполнения при преобразовании выражения в тип данных datetime.»

если я не использую предложение where, то все в порядке. как это могло случиться?

SELECT * FROM (SELECT AKTDET.*, DATEDIFF(day,aktdet.Bezahlt_am, getdate()- 50) as datumsdifferenz FROM (SELECT  Convert(datetime,AKTDET.von_num - 2.0,121) as [Bezahlt_am], AKT.KENNUNG, AKTDET.* FROM AKT INNER JOIN AKTDET ON AKT.DSN = AKTDET.AKT_DSN Inner JOin FLDART ON AKTDET.Fldart_Dsn = FLDART.DSN WHERE FLDART.Kürzel = 'bezahlt am') AS AKTDET ) AS AKTDET

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

datumsdifferenz Bezahlt_am  KENNUNG     AKT_DSN
700 2016-12-21 00:00:00.000        340  690837DC-C521-47A7-B845-0B3036CADA07
391 2017-10-26 00:00:00.000       1887  27BC0276-0FAF-4787-BC69-4F7CC8F4D44A
391 2017-10-26 00:00:00.000       1887  27BC0276-0FAF-4787-BC69-4F7CC8F4D44A
392 2017-10-25 00:00:00.000       1890  102CA803-8EA7-48CB-95AE-AA2F8F686715

если я использую select top 80... WHERE datumsdifferenz > 0.0 также все будет работать нормально.

если я использую select top 90... WHERE datumsdifferenz > 0.0 это снова выбросит эти странные ошибки.

если я использую временную таблицу и сделаю сравнение, после этого она будет работать?!

1 Ответ

0 голосов
/ 10 января 2019

Я нашел решение для себя. Оптимизатор запросов сначала выполняет сканирование всей таблицы с помощью convert, если я использую предложение where.

подзапрос с FLDART_DSN = (ВЫБЕРИТЕ ТОП 1 DSN ОТ FLDART, ГДЕ FLDART.Kürzel = 'bezahlt am') будет обработан после предложения external where. вся таблица будет отсканирована в этой ситуации. но таблица содержит данные, которые не являются значениями даты. и это причина, по которой преобразование не будет выполнено в этой ситуации с предложением external where.

Решение:

SELECT * FROM (SELECT case When von_num < 90000.0 AND von_num > -400000.0 then convert(datetime,VON_NUM,104) END as bezahlt_am, *  FROM (SELECT  * FROM _TEST WHERE FLDART_DSN = (SELECT TOP 1 DSN FROM FLDART WHERE FLDART.Kürzel = 'bezahlt am')) as test) as test WHERE FLDART_DSN = (SELECT TOP 1 DSN FROM FLDART WHERE FLDART.Kürzel = 'bezahlt am') AND bezahlt_am  > GETDATE() - 100.0

SELECT convert(datetime,90000.0,104) -- 2146-05-31 00:00:00.000
SELECT convert(datetime,-40000.0,104) -- 1790-06-26 00:00:00.000
...