Условное ветвление в SQL на основе типа переменной - PullRequest
3 голосов
/ 30 марта 2009

Я выбираю значение из таблицы, которое может быть целым числом или nvarchar. Он хранится как nvarchar. Я хочу условно вызвать функцию, которая преобразует это значение, если оно является целым числом (то есть если оно может быть преобразовано в целое число), в противном случае я хочу выбрать nvarchar без преобразования.

Это попадание в базу данных SQL Server 2005.

select case
    when T.Value (is integer) then SomeConversionFunction(T.Value)
    else T.Value
end as SomeAlias

from SomeTable T

Обратите внимание, что это часть "(целое число)", с которой у меня проблемы. Заранее спасибо.

UPDATE

Проверьте комментарий к ответу Яна. Это объясняет, почему и что немного лучше. Спасибо всем за их мысли.

Ответы [ 7 ]

4 голосов
/ 30 марта 2009
 select case
     when ISNUMERIC(T.Value) then T.Value 
     else SomeConversionFunction(T.Value)
 end as SomeAlias

Кроме того, вы рассматривали возможность использования типа данных sql_variant?

3 голосов
/ 30 марта 2009

Набор результатов может иметь только один тип, связанный с ним для каждого столбца, вы получите сообщение об ошибке, если первая строка преобразуется в целое число и имеются следующие строки:

Сообщение 245, Уровень 16, Состояние 1, Строка 1 Ошибка преобразования при преобразовании значения nvarchar 'word' в тип данных int.

попробуйте это, чтобы увидеть:

create table  testing
(
strangevalue   nvarchar(10)
)

insert into testing values (1)
insert into testing values ('word')
select * from  testing

select
    case
        when ISNUMERIC(strangevalue)=1 THEN CONVERT(int,strangevalue)
        ELSE strangevalue
     END
FROM testing

Лучше всего вернуть два столбца:

select
    case
        when ISNUMERIC(strangevalue)=1 THEN CONVERT(int,strangevalue)
        ELSE NULL
     END AS StrangvalueINT
    ,case
        when ISNUMERIC(strangevalue)=1 THEN NULL
        ELSE strangevalue
     END AS StrangvalueString
FROM testing

или ваше приложение может проверить числовые значения и выполнить специальную обработку.

2 голосов
/ 30 марта 2009

ISNUMERIC . Тем не менее, это принимает +, - и десятичные дроби, поэтому требуется больше работы.

Однако вы не можете иметь столбцы как оба типа данных за один раз: вам понадобятся 2 столбца.

Я бы посоветовал вам разобраться с этим в вашем клиенте или использовать ISNUMERIC замену

2 голосов
/ 30 марта 2009

Вы не можете иметь столбец, который иногда является целым числом, а иногда и строкой. Верните строку и проверьте ее, используя int.TryParse () в коде клиента.

1 голос
/ 30 марта 2009

Чтобы прояснить некоторые другие ответы, ваш оператор SQL не может возвращать разные типы данных в одном столбце (похоже, что другие ответы говорят, что вы не можете хранить разные типы данных в одном столбце - все ваши представления являются резкими).

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

Если вы выбираете только одно значение, оно может вернуть строку или число, однако ваш интерфейсный код должен будет иметь возможность возвращать различные типы данных.

1 голос
/ 30 марта 2009

IsNumeric поможет вам в этом. Затем вы можете добавить дополнительный код, чтобы проверить, является ли оно целым числом

например:

select top 10 
    case 
        when isnumeric(mycolumn) = 1 then 
            case 
                when convert(int, mycolumn) = mycolumn then
                    'integer'
                else
                    'number but not an integer'
            end
        else 
            'not a number'
    end 
from mytable
0 голосов
/ 30 марта 2009

Просто чтобы добавить к другим комментариям о невозможности вернуть разные типы данных в одном столбце ... Столбцы базы данных должны знать, какой тип данных они содержат. Если они этого не делают, это должен быть БОЛЬШОЙ красный флаг, что у вас где-то есть проблема с дизайном, которая почти гарантирует будущие головные боли (как этот).

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