Почему сравнение не работает в CONVERT?

можно ли использовать оператор сравнения в функции 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: Is оператор, определяющий способ объединения двух выражений для получения одного результата. 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 ответов


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

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

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

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

...

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

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

кроме того, если вы посмотрите на документацию для преобразование, вы увидите, что 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.