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

0

Вопрос

Я работаю с azure ADF, и у меня возникают проблемы при выполнении этого запроса в azure ADF:

SELECT COUNT(*) AS c
FROM TABLE 
WHERE CONVERT(date, (FORMAT(DATEADD(second, CONVERT(bigint, TS) / 1000, '19700101'), 'yyyy-MM-dd'))) = CONVERT(Date, GETDATE())

Вывод-это ошибка

Арифметическое переполнение

но если я изменю = К >=, запрос работает и возвращает результат.

То TS это UNIXTIMESTAMP Нравится 1637680012264.

Используя комбинацию >= и < это не нормально, потому что я имею дело с не непрерывными днями (мне нужно использовать WHERE TS IN (date1, date2, etc...)

Кто-нибудь может мне помочь? Заранее спасибо

azure azure-data-factory sql sql-server
2021-11-23 15:02:27
2

Лучший ответ

0

Предпочтительно, я бы поменял таблицу для хранения datetime2 ценности вместо запутанного хлама эпохи.

Но, предполагая, что вы не можете исправить дизайн...

По мнению Ларну, вы не хотите применять вычисления к столбцу, и вы определенно не хотите применять FORMAT() с обеих сторон, потому чтоFORMAT() это абсолютная собака.

Вместо этого я бы нашел границы на сегодня и использовал открытый диапазон. Это предполагает, что TS колонка должна быть bigint:

DECLARE @d date = GETDATE();

DECLARE @start bigint = DATEDIFF(SECOND, '19700101', @d),
        @end   bigint = DATEDIFF(SECOND, '19700101', DATEADD(DAY, 1, @d));

SELECT COUNT(*) AS c
FROM dbo.[TABLE]
WHERE TS >= @start * 1000 
  AND TS <  @end   * 1000;

Это позволяет избежать любых накладных расходов на форматирование, запутанных и ненужных выражений преобразования (TS должно быть, уже есть bigint, верно, так почему же явное CONVERT()?).


Если вам нужны несмежные даты, хорошо, мы все еще можем сделать это с гораздо меньшим злоупотреблением таблицей. Просто создайте таблицу #temp или переменную таблицы с вычисляемыми столбцами, вставьте туда несколько ваших дат, а затем внешне присоединитесь к ней.

DECLARE @d table
(
  d datetime2, 
  s AS CONVERT(bigint, 
    DATEDIFF(SECOND, '19700101', d)) * 1000,
  e AS CONVERT(bigint, 
    DATEDIFF(SECOND, '19700101', DATEADD(DAY, 1, d))) * 1000
);

INSERT @d(d) VALUES('20211123'),('20211007');

-- if you want a row per day:
SELECT d.d, COUNT(t.TS) AS c
FROM @d AS d
LEFT OUTER JOIN dbo.[TABLE] AS t
   ON  t.TS >= d.s
   AND t.TS <  d.e
GROUP BY d.d
ORDER BY d.d;

-- if you just want a total count:
SELECT COUNT(t.TS) AS c
FROM @d AS d
LEFT OUTER JOIN dbo.[TABLE] AS t
   ON  t.TS >= d.s
   AND t.TS <  d.e;

Гораздо больше о современных вредных привычках и лучших практиках:

2021-11-23 15:46:34

Спасибо, Аарон, несмотря на то, что ваше решение-это не то, что я искал, вы просветили мою команду: "Это не источник ошибки. DATEADD никогда не сможет добавить 3 миллиарда секунд к 1970 году. Так что, может быть, разделите еще раз и попробуйте добавить по минутам, если вас интересует только дата, точность второго уровня не должна быть важной. Можете ли вы предоставить пару выборочных значений для TS и ожидаемые результаты для них". Поэтому преобразовал МЕТКУ ВРЕМЕНИ в ДНЯХ, разделив ее на 60*60*1000*24
Salvatore Bonanno

@SalvatoreBonанно, но это все еще крайне неэффективный способ решения проблемы. Вы хотите, чтобы математика была по другую сторону пункта "где", поверьте мне. Если только не TS столбец не индексируется, и вы точно знаете, что никогда не будете его индексировать.
Aaron Bertrand

Да, я видел решение с помощью временной таблицы. Наиболее проблематичным является то, что я могу иметь доступ только для чтения к таблице ( таблица находится в облаке), поэтому я ничего не знаю об индексе на ней (это тоже может быть представление!) . Итак, математическая задача решила проблему на данный момент, но я постараюсь оптимизировать ее, как вы сказали.
Salvatore Bonanno
-1

Я повторил это в своей локальной среде ADF и смог успешно получить результаты.

Ниже приведена примерная таблица:

Здесь у меня есть 3 строки с датой "2021-11-23" и 2 строки с ‘2021-11-24’. TS столбец имеет дату в формате метки времени UNIX и dt_format столбец предназначен для отображения TS столбец в формате даты.

enter image description here

АДС:

Используя действие поиска, получите количество строк, в которых в столбце TS указана сегодняшняя дата. (Я использую ваш код с другой таблицей).

SELECT COUNT(*) AS c
FROM tb1 
WHERE CONVERT(date, (FORMAT(DATEADD(second, CONVERT(bigint, TS) / 1000, '19700101'), 'yyyy-MM-dd'))) = CONVERT(Date, GETDATE())

enter image description here

Выход:

enter image description here

2021-11-23 15:28:21

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................