Почему сравнение не работает в CONVERT? - PullRequest
6 голосов
/ 06 января 2012

Можно ли использовать оператор сравнения в функции CONVERT или CAST?

У меня есть утверждение, которое выглядит так:

SELECT
    ...
    CASE field
        WHEN 'Y' THEN 1  # If Y then True
        ELSE 0           # Anything else is False
    END
    ...
FROM ...

Подобное происходит с несколькими полями, поэтому я хотел бы изменить его на более короткую версию:

SELECT
    ...
    CONVERT(BIT, field = 'Y')
    ...
FROM ...

Но MSSQL выдает ошибку Incorrect syntax near '='.

Моя интерпретация помощи заключается в том, что она должна работать:

  • CONVERT ( data_type [ ( length ) ] , expression [ , style ] )
  • expression: expression { binary_operator } expression
  • binary_operator: оператор, который определяет способ объединения двух выражений для получения одного результата. Двоичный_оператор может быть арифметическим оператором, оператором присваивания (=), побитовым оператором, оператором сравнения, логическим оператором, оператором конкатенации строк (+) или унарным оператором.
  • comparison operator: ( = | > | < | >= | <= | <> | != | !< | !> )

Я провел несколько тестов и получил следующие результаты:

SELECT CONVERT(BIT, 0)       // 0
SELECT CONVERT(BIT, 1)       // 1
SELECT CONVERT(BIT, 1+2)     // 1
SELECT CONVERT(BIT, 1=2)     // Error
SELECT CONVERT(BIT, (1=2))   // Error
SELECT CONVERT(BIT, (1)=(2)) // Error

1 Ответ

4 голосов
/ 06 января 2012

Я думаю, вы неправильно истолковали документацию для CONVERT.В документации для CONVERT нет ничего, в котором говорится, что он будет обрабатывать выражение, использующее операторы сравнения, только то, что он принимает выражение.Оказывается, CONVERT не обрабатывает каждое допустимое выражение SQL.По крайней мере, он не может обработать результаты выражения, которое использует оператор сравнения.

Если вы проверите документацию для Операторы , вы увидите, что операторы сравнения (чтов этом случае вы хотите, чтобы = возвращал тип данных Boolean и используется в предложениях WHERE и операторах управления потоком.Из документации для операторов:

Результат оператора сравнения имеет логический тип данных, который имеет три значения: TRUE, FALSE и UNKNOWN.Выражения, которые возвращают логический тип данных, называются логическими выражениями.

В отличие от других типов данных SQL Server, логический тип данных не может быть указан как тип данных столбца или переменной таблицы и не может быть возвращен внабор результатов.

...

Выражения с логическими типами данных используются в предложении WHERE для фильтрации строк, соответствующих условиям поиска, и в выражениях языка управления потоком, таких какЕсли и WHILE ...

Это помогает объяснить, почему SQL, такой как SELECT 1=2, является недопустимым SQL, потому что он создает набор результатов с типом данных Boolean, который, как говорится в документации, не являетсяпозволил.Это также объясняет, почему необходима конструкция CASE WHEN, поскольку она может оценивать операторы сравнения и возвращать одно значение типа данных, которое SQL Server может возвращать в наборе результатов.

Более того, если вы посмотрите надокументацию для CONVERT вы увидите, что Boolean не поддерживается ни в CAST, ни в CONVERT (см. таблицу в середине страницы, тип данных Boolean втам).

Для ваших целей, я думаю, вы застряли, используя CASE WHEN.Если это поможет, вы можете написать все это в одной строке:

CASE WHEN field = 'Y' THEN 1 ELSE 0 END

В качестве альтернативы, вы можете создать UDF для обработки выражения CASE (что-то вроде dbo.func_DoCase(field, 'Y', 1, 0)), но лично я бы просто придерживался CASE WHEN.

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