Есть ли способ в T-SQL преобразовать nvarchar в int и вернуть значение по умолчанию или NULL в случае сбоя преобразования?
116
Используйте функцию TRY_CONVERT .
Создайте пользовательскую функцию. Это позволит избежать проблем, о которых упоминал Федор Хайду в отношении валюты, дробных чисел и т. Д .:
CREATE FUNCTION dbo.TryConvertInt(@Value varchar(18))
RETURNS int
AS
BEGIN
SET @Value = REPLACE(@Value, ',', '')
IF ISNUMERIC(@Value + 'e0') = 0 RETURN NULL
IF ( CHARINDEX('.', @Value) > 0 AND CONVERT(bigint, PARSENAME(@Value, 1)) <> 0 ) RETURN NULL
DECLARE @I bigint =
CASE
WHEN CHARINDEX('.', @Value) > 0 THEN CONVERT(bigint, PARSENAME(@Value, 2))
ELSE CONVERT(bigint, @Value)
END
IF ABS(@I) > 2147483647 RETURN NULL
RETURN @I
END
GO
-- Testing
DECLARE @Test TABLE(Value nvarchar(50)) -- Result
INSERT INTO @Test SELECT '1234' -- 1234
INSERT INTO @Test SELECT '1,234' -- 1234
INSERT INTO @Test SELECT '1234.0' -- 1234
INSERT INTO @Test SELECT '-1234' -- -1234
INSERT INTO @Test SELECT '$1234' -- NULL
INSERT INTO @Test SELECT '1234e10' -- NULL
INSERT INTO @Test SELECT '1234 5678' -- NULL
INSERT INTO @Test SELECT '123-456' -- NULL
INSERT INTO @Test SELECT '1234.5' -- NULL
INSERT INTO @Test SELECT '123456789000000' -- NULL
INSERT INTO @Test SELECT 'N/A' -- NULL
SELECT Value, dbo.TryConvertInt(Value) FROM @Test
Ссылка: я широко использовал эту страницу при создании своего решения.
Да :). Попробуй это:
ISNUMERIC()
Есть несколько проблем, на которые указал Федор Хайду .Он возвращает истину для таких строк, как
$
(это валюта),
или.
(оба являются разделителями)+
и-
.источник
ISNUMERIC
чтобы этот ответ мог быть использован для непроверенных данных (и вам не понадобитсяISNUMERIC
проверка в первую очередь для правильно проверенных данных). Автор признает наличие этих проблем, но не решает их.TRY_CONVERT
/TRY_CAST
, которые явно предназначены для решения вопроса OP. Этот ответ был написан до выпуска SQL 2012.Я бы предпочел создать такую функцию, как TryParse, или использовать
TRY-CATCH
блок T-SQL, чтобы получить то, что вы хотели.ISNUMERIC не всегда работает должным образом. Код, приведенный ранее, выйдет из строя, если вы сделаете следующее:
НАБОР @text = '$'
Знак $ можно преобразовать в тип данных money, поэтому
ISNUMERIC()
в этом случае возвращается true. То же самое будет для '-' (минус), ',' (запятая) и '.' персонажи.источник
ISNUMERIC()
Возвращается1
также для,
и.
.Как уже упоминалось, вы можете столкнуться с несколькими проблемами, если используете
ISNUMERIC
:Если вам нужна надежная конверсия, вам нужно будет написать ее самостоятельно.
Обновление : Моя новая рекомендация - использовать промежуточное тестовое преобразование
FLOAT
для проверки числа. Этот подход основан на комментарии Адрианма . Логику можно определить как встроенную функцию с табличным значением:Некоторые тесты:
Результаты аналогичны ответу Джозефа Стертеванта со следующими основными отличиями:
.
или,
имитации поведения собственныхINT
преобразований.'1,234'
и'1234.0'
вернутьсяNULL
.'00000000000000001234'
оценивается в12
. Увеличение длины параметра приведет к ошибкам в числах, которые переполняютсяBIGINT
, например BBAN (базовые номера банковских счетов), например'212110090000000235698741'
.Снято : описанный ниже подход больше не рекомендуется, так как он оставлен только для справки.
Приведенный ниже фрагмент работает с неотрицательными целыми числами. Он проверяет, что ваша строка не содержит нецифровых символов, не пуста и не переполняется (превышая максимальное значение для
int
типа). Однако он также даетNULL
действительные целые числа, длина которых превышает 10 символов из-за ведущих нулей.Если вы хотите поддерживать любое количество ведущих нулей, используйте приведенное ниже. Вложенные
CASE
операторы, хотя и громоздкие, необходимы для ускорения оценки короткого замыкания и снижения вероятности ошибок (возникающих, например, из-за передачи отрицательной длины вLEFT
).Если вы хотите поддерживать положительные и отрицательные целые числа с любым количеством ведущих нулей:
источник
С уважением.
Я написал полезную скалярную функцию для имитации функции TRY_CAST SQL SERVER 2012 в SQL Server 2008.
Вы можете увидеть это по следующей ссылке ниже, и мы помогаем друг другу улучшать это. Функция TRY_CAST для SQL Server 2008 https://gist.github.com/jotapardo/800881eba8c5072eb8d99ce6eb74c8bb
Пример:
На данный момент поддерживает только типы данных INT, DATE, NUMERIC, BIT и FLOAT.
Я надеюсь, вы сочтете это полезным.
КОД:
источник
В ответе Джозефа указано, что ISNUMERIC также обрабатывает научную нотацию, такую как '1.3e + 3', но его ответ не обрабатывает этот формат числа.
Преобразование в деньги или флоат сначала решает как валютные, так и научные вопросы:
Функция завершится ошибкой, если число больше bigint.
Если вы хотите вернуть другое значение по умолчанию, оставьте эту функцию, чтобы она была универсальной, а затем замените null:
источник
Я знаю, что это некрасиво, но это просто. Попробуй это:
источник
Мое решение этой проблемы заключалось в создании функции, показанной ниже. В мои требования входило, что число должно быть стандартным целым числом, а не BIGINT, и мне нужно было разрешить отрицательные числа и положительные числа. Я не нашел обстоятельств, при которых это не помогло бы.
источник