Каков наилучший способ пропустить прошлые ошибки приведения во время обновления SQL и продолжить?

#sql #sql-server #tsql

#sql #sql-server #tsql

Вопрос:

У меня есть столбец varchar в таблице, где я хочу вставить его данные в другой столбец в той же таблице, где его тип данных — money. Некоторые значения в исходном столбце представляют собой большие числа, которые я хочу игнорировать и просто хочу присвоить этим значениям значение NULL.

Я попробовал это:

 UPDATE MyTable SET destCol = CASE WHEN IsNumeric(sourceCol) = 1 THEN sourceCol END
  

Но это выдает «Ошибку арифметического переполнения …» при попытке проверить большие числа.

Я думаю, мне может понадобиться какая-то функция или использовать блок try / catch в хранимой процедуре, чтобы получить желаемую функциональность.

Обновить

Я забыл упомянуть, что некоторые значения в исходном столбце имеют текстовые значения, которые вообще не могут быть преобразованы в money, для них также необходимо установить значение NULL.

Ответ №1:

Если проблема вызвана огромными числами, вы можете ограничиться теми, которые можно преобразовать в money

 UPDATE MyTable
SET destCol = CAST(sourceCol AS money)
WHERE  sourceCol < 922337203685477.5807
  

money диапазон — это деньги от -922,337,203,685,477.5808 до 922,337,203,685,477.5807

[ПРАВИТЬ]

Итак, у вас есть столбец varchar. Вы можете сделать что-то вроде этого:

 UPDATE MyTable
SET destCol = 
    CASE WHEN Len(sourceCol) < 15 AND ISNUMERIC(sourceCol) = 1 THEN CAST(sourceCol AS MONEY) ELSE 0 END
  

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

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

2. select ISNUMERIC('1d2'); select CAST('1d2' as money) — приводит к 1 , за которым следует ошибка. Я всегда буду голосовать за то, ISNUMERIC чтобы быть самой бесполезной функцией когда-либо…

3. @Damien_The_Unbeliever — верно :).

4. ISNUMERIC для победы!

Ответ №2:

Предполагая, что вы просто хотите преобразовать простые числа, тогда что-то вроде:

 UPDATE MyTable SET destCol = CASE WHEN not sourceCol like '%[^0-9]%' and LEN(sourceCol) <= 8 THEN sourceCol END
  

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

Проблема, как всегда, с ISNUMERIC заключается в том, что это отвечает на вопрос, который никому не нужен (может ли эта строка быть преобразована в любой из числовых типов?), А не на что-то полезное (может ли эта строка быть преобразована в числовой тип ‘X’?)