SQL IsNumeric возвращает True, но отчеты SQL «Преобразование не выполнено» - PullRequest
10 голосов
/ 20 февраля 2009

Предполагая следующие данные:

Column1 (data type: varchar(50))
--------
11.6
-1
1,000
10"    
Non-Numeric String

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

SELECT CASE
       WHEN IsNumeric(Replace(Column1, '"', '')) = 1 THEN Replace(Column1, '"', '')
       ELSE 0
   END AS NumericValue

SQL сообщает:

Сбой преобразования при преобразовании значения varchar '11 .6' в тип данных int.

Почему? Я также пытался принудительно разыграть это:

SELECT CASE
       WHEN IsNumeric(Replace(Column1, '"', '')) = 1 THEN cast(Replace(Column1, '"', '') AS float)
       ELSE 0
   END AS NumericValue

И я получил:

Ошибка преобразования типа данных varchar в float.

Ответы [ 8 ]

11 голосов
/ 20 февраля 2009

Вам необходимо заменить запятую на точку:

CAST(REPLACE(column, ',', '.') AS FLOAT)

SQL Server выводит десятичный разделитель, определенный с помощью локали, но ничего не понимает, кроме периода в CAST s, для числовых типов.

5 голосов
/ 18 декабря 2012

Сначала преобразуйте строку в деньги, затем преобразуйте ее в любой другой числовой формат, поскольку тип money всегда дает истинную числовую строку. Тогда вы никогда не увидите ошибки.

Попробуйте следующее в своем запросе, и вы поймете, о чем я говорю. Оба вернутся 2345,5656. Тип данных Money округляется до 4 знаков после запятой, и, следовательно, приведение вызывает округление до 4 знаков после запятой.

SELECT CAST('2,345.56556' as money), CAST('$2,345.56556' as money)

Cast (приведение («2344» в качестве денег) в качестве float) будет работать идеально или приведение (приведение («2344» в качестве денег) к десятичной (7,2)) также будет работать.

Даже приведение (CAST ($ 2,345.56556 в качестве денег) как int) будет отлично работать, округляя до ближайшего целого числа.

3 голосов
/ 20 февраля 2009

Существует много проблем с SQL в числовом формате. Например:

select isnumeric('1e5')

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

http://www.tek -tips.com / faqs.cfm? FID = 6423

1 голос
/ 27 июня 2012

IsNumeric(' ') также возвращает 1, но затем CAST при увеличении int. Брендан выше говорит, напишите свою собственную функцию. Он прав.

1 голос
/ 20 февраля 2009

Кайл

Я думаю, что это решает проблему. Проблема заключается в том, что предложение ELSE инициализирует ваш результат как INTEGER. Делая явное приведение типа к FLOAT и добавляя предложение Quassnoi, это похоже на работу.

DECLARE @MyTable TABLE (Column1 VARCHAR(50))
INSERT INTO @MyTable VALUES('11.6')
INSERT INTO @MyTable VALUES('-1')
INSERT INTO @MyTable VALUES('1,000')
INSERT INTO @MyTable VALUES('10"    ')
INSERT INTO @MyTable VALUES('Non-Numeric String')

SELECT CASE WHEN ISNUMERIC(REPLACE(Column1,'"','')) = 1 THEN REPLACE(REPLACE(Column1,'"',''), ',', '.') ELSE CAST(0 AS FLOAT) END
FROM @MyTable

С уважением,
Ливны

1 голос
/ 20 февраля 2009

ISNUMERIC возвращает 1, когда входное выражение оценивается как допустимое целое число, число с плавающей запятой, денежный или десятичный тип;

Таким образом, проблема в том, что это действительное число, но не действительное число.

0 голосов
/ 22 апреля 2016

Я только что встретил эту проблему.

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

CONVERT(numeric, CONVERT(money, '.')) 

ПРИМЕЧАНИЕ:

  1. Поддерживается в SQL Server 2008 или выше.
  2. Деньги диапазон : -922,337,203,685,477,5808 до 922,337,203,685,477.5807 - четыре знака после запятой .
0 голосов
/ 03 ноября 2015

Это решение работает не во всех случаях (в частности, числа с деньгами и / или тысячами разделителей). Объединить экспонентное представление до конца числа, представленного строкой ... Оттуда ISNUMERIC () работает нормально. Примеры ниже:

-- CURRENT ISNUMERIC RESULTS
SELECT ISNUMERIC('11.6'); --1
SELECT ISNUMERIC ('-1'); --1
SELECT ISNUMERIC('1,000'); --1
SELECT ISNUMERIC('10"'); --0
SELECT ISNUMERIC('$10'); --1

-- NEW ISNUMERIC RESULTS
SELECT ISNUMERIC('11.6'+'e+00'); --1
SELECT ISNUMERIC ('-1'+'e+00'); --1
SELECT ISNUMERIC('1,000'+'e+00'); --0
SELECT ISNUMERIC('10"'+'e+00'); --0
SELECT ISNUMERIC('$10'+'e+00'); --0

Это, по крайней мере, стандартизирует формат для использования функции REPLACE ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...