SQL Server - логічний літерал?


77

Як написати буквальне булеве значення в SQL Server? Див. Зразок використання:

select * from SomeTable where PSEUDO_TRUE

інший зразок:

if PSEUDO_TRUE
begin
  select 'Hello, SQL!'
end 

Примітка: Наведений вище запит не має нічого спільного з тим, як я його буду використовувати. Це лише тестування буквального логічного значення.


1
Ні, просто хочу перевірити, чи істина працює в реченні where. По-перше, я не знаю буквального значення для true і false.
dpp

4
SQL Server не має тип даних Boolean , ні необхідні оператори IS TRUE, IS UNKNOWNі т.д. (хоча SQL-99 Стандарт має і інше). Типовим рішенням є використання CHAR(1)обмеженого стовпця CHECK (col1 IN ('T', 'F')).
onedaywhen

Відповіді:


76

SQL Server не має логічного типу даних . Як зазначив @Mikael, найближчим наближенням є біт. Але це числовий тип, а не булевий тип. Крім того, він підтримує лише 2 значення - 0або 1(і одне незначне, NULL).

SQL (стандартний SQL, як і діалект T-SQL) описує тризначну логіку . Логічний тип для SQL повинен підтримувати 3 значення - TRUE, FALSEі UNKNOWN(а також не-значення NULL). Так що bitнасправді тут не вдалий матч.

Враховуючи, що SQL Server не підтримує тип даних , ми не повинні сподіватися, що зможемо писати літерали цього "типу".


7
Цікаво, що могло змусити команду SQL Server мати біт замість логічного типу даних (зі значеннями true і false). Логічний настільки природний для всіх доменів програм. Я вважаю, що вони все одно використовуватимуть 1 байт для зберігання бітового типу даних. Навіть із внутрішнім сховищем, яке вони могли б підтримувати, Trueта Falseяк синтаксичний цукор принаймні в сценаріях SQL.
RBT

Шанси полягають у тому, що це так у C. Немає таких значень trueабо false, а натомість істинних (не 0) та хибних (0) значень. C99 додав stdbool.h, який лише визначає макроси для них, але при подальшій обробці будь-які такі значення замінюються на 1 та 0 відповідно.
Драгаш

39
select * from SomeTable where 1=1

1
Це працює! На жаль, це не літерал, результат 1=1логічного значення true, але це не буквально.
dpp

18

Більшість баз даних приймають це:

select * from SomeTable where true

Однак деякі бази даних (наприклад, SQL Server, Oracle) не мають логічного типу. У цих випадках ви можете використовувати:

select * from SomeTable where 1=1

До речі, якщо ви створюєте пропозицію sql where вручну, це основа для спрощення вашого коду, тому що ви можете не знати, чи умова, яку ви збираєтесь додати до речення where, є першою (перед якою має стояти "WHERE"), або наступний (якому повинен передувати "AND"). Завжди починаючи з "WHERE 1=1", всі умови (якщо такі є), додані до речення where, передують "AND".


1
An expression of non-boolean type specified in a context where a condition is expected, near 'group'Я використовую MSSQL
dpp

3
Шановні прихильники голосу! Початкове запитання, на яке я відповів, не вказувало тип сервера "sql-server", тому я відповів на загальне питання загальною відповіддю із застереженням щодо "більшості баз даних". Я не розумію, чому це заслуговує на голосування проти.
Чеська

1
Краще видаліть свою відповідь, перш ніж отримувати більше голосів проти. Якось це моя вина, що я просто вказав, що SQLні MSSQL.
dpp

2
@dpp - чи прийнятна зараз відповідь? Я дав альтернативу, яку прийматимуть усі бази даних
Bohemian

2
Кожен сервер Microsoft SQL є сервером бази даних SQL, але не кожен сервер баз даних SQL є сервером Microsoft SQL. Подібно до того, як кожне яблуко - це фрукт, але не кожен фрукт - це яблуко (або, можливо, у випадку МС - груша :)
інженер, що здійснив зворотний

17

Це не згадується в жодній іншій відповіді. Якщо вам потрібне значення, яке орми (повинно) гідратувати як логічне значення, ви можете використовувати

CONVERT (bit, 0) - false CONVERT (bit, 1) - true

Це дає вам трохи, що не є логічним значенням. Ви не можете використовувати це значення в операторі if, наприклад:

IF CONVERT(bit, 0)
BEGIN
    print 'Yay'
END

не розбирав би. Вам все одно потрібно було б писати

IF CONVERT(bit, 0) = 0

Тож це не дуже корисно.


16

На думку Microsoft : синтаксис пошуку є

[ WHERE <search_condition> ]*

А умовою пошуку є:

<search_condition> ::= 
    { [ NOT ] <predicate> | ( <search_condition> ) } 
    [ { AND | OR } [ NOT ] { <predicate> | ( <search_condition> ) } ] 
[ ,...n ] 

І предикат:

<predicate> ::= 
    { expression { = | < > | ! = | > | > = | ! > | < | < = | ! < } expression 

Як бачите, для порівняння завжди потрібно писати два вирази. Тут умовою пошуку є логічний вираз типу 1 = 1, a! = B

Не плутайте пошукові вирази з логічними константами типу "True" або "False" . Ви можете призначити логічні константи змінним BIT

DECLARE @B BIT
SET @B='True'

але в TSQL ви не можете використовувати логічні константи замість булевих виразів, як це:

SELECT * FROM Somewhere WHERE 'True'

Це не спрацює.

Але ви можете використовувати булеві константи, щоб побудувати двосторонній вираз пошуку як:

SEARCH * FROM Somewhere WHERE 'True'='True' 

8

SQL Server не має буквальних істинних чи помилкових значень. Вам доведеться використовувати 1=1метод (або подібний) у рідкісних випадках, коли це потрібно.

Одним із варіантів є створення власних іменованих змінних для true та false

DECLARE @TRUE bit
DECLARE @FALSE bit
SET @TRUE = 1
SET @FALSE = 0

select * from SomeTable where @TRUE = @TRUE

Але вони існуватимуть лише в межах пакету (вам доведеться повторно оголосити їх у кожній партії, в якій ви хочете їх використовувати)


1
Це не працює, як пояснено у відповідях вище. "Вираз небулевого типу, зазначений у контексті, де очікується умова, біля '@TRUE'"
Майк Чемберлен,

2
+1 це спрацювало для мене уcase when exists( select 1 from project.quota_group_supplier qgs with (nolock) where qgs.project_quota_id=qg.project_quota_id) then @TRUE else @FALSE end
Маслоу

6

Ви можете використовувати значення 'TRUE'і 'FALSE'. З https://docs.microsoft.com/en-us/sql/t-sql/data-types/bit-transact-sql :

Значення рядка TRUE і FALSE можуть бути перетворені в бітові значення: TRUE перетворюється в 1, а FALSE - в 0.


1
Не могли б ви пояснити, що ви маєте на увазі? Це повинно добре працювати в реченнях WHERE.
Matt H

1
Напр select 'TRUE' where 'TRUE'. Він також не може бути змістовно використаний у контексті select, а також не працює речення where. SQL-аналізатор скаржиться на те, що значення "TRUE" не є логічним. Так само select TRUE where TRUEнедійсний в обох частинах. Загалом. Як правило, це не працює на MS-SQL.
Себастьян Мах

1
Гаразд, але це працює при порівнянні значень, таких як WHERE column = 'TRUE'або IF @value = 'FALSE'.
Matt H

5

Як написати буквальне булеве значення в SQL Server?
виберіть * з SomeTable, де PSEUDO_TRUE

Немає такого.

Ви повинні порівняти значення з чимось, використовуючи = < > like .... Найближчим до вас булевим значенням у SQL Server є біт . І це ціле число, яке може мати значення null, 0і 1.


2

Ви повинні врахувати, що "справжнє значення" - це все, крім 0, а не тільки 1. Отже, замість 1 = 1 ви повинні написати 1 <> 0.

Тому що, коли ви будете використовувати параметр (@param <> 0), у вас можуть виникнути проблеми з перетворенням.

Найбільш відомим є Access, який переводить значення True на контролі як -1 замість 1.


1

Я ставлю під сумнів значення використання логічного значення в TSQL. Кожного разу, коли я починав бажати Booleans & For Loops, я розумів, що підходжу до проблеми як програміст на C, а не програміст на SQL. Проблема стала тривіальною, коли я перемикав передачі.

У SQL ви маніпулюєте наборами даних. "WHERE BOOLEAN" неефективний, оскільки не змінює набір, з яким ви працюєте. Вам потрібно порівняти кожен рядок з чимось, щоб речення фільтра було ефективним. Таблиця / результат - це iEnumerable, оператор SELECT - цикл FOREACH.

Так, "WHERE IsAdmin = True" читати приємніше, ніж "WHERE IsAdmin = 1"

Так, "WHERE True" було б приємніше, ніж "WHERE 1 = 1, ..." при динамічній генерації TSQL.

і, можливо, передача логічного значення збереженому proc може зробити оператор if більш читабельним.

Але здебільшого, чим більше таблиць IF, WHILE та Temp є у вашому TSQL, тим більша ймовірність того, що вам слід його рефакторинг.


1

Сподіваюся, це відповідає наміру питання. Незважаючи на те, що в SQL Server немає логічного значення, якщо у вас є база даних, яка мала логічні типи, яка була перекладена з Access, фраза, яка працює в Access, була "... WHERE Foo" (Foo - ім'я логічного стовпця). Його можна замінити на "... WHERE Foo <> 0" ... і це працює. Удачі!


1

Ви можете використовувати рядки "True" або "False" для імітації даних типу bolean.

Select *
From <table>
Where <columna> = 'True'

Я думаю, що таким чином, можливо, повільно, ніж просто поставити 1, оскільки це вирішено за допомогою функції Convert_implicit.


-1
select * from SomeTable where null is null

або

select * from SomeTable where null is not null

може це найкращий показник?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.