微软 SQL Server 中是否有像 MySQL 中那样的布尔数据类型?

446

微软SQL Server中是否有像MySQL中那样的布尔数据类型?

如果没有,MS SQL Server中的替代方法是什么?


9
实际上,MySQL没有boolean数据类型。 - user330315
9个回答

617

您可以使用BIT数据类型来表示布尔数据。一个BIT字段的值是1、0或null。


62
通常情况下,将0解释为假(FALSE),将1解释为真(TRUE),当允许使用Nulls时,它们将被视为NULL。 - reido113
24
请注意,BIT 不等同于布尔类型。如果一个标量函数返回一个 BIT 类型的值,仍需要判断它是否为 0 或者 1。例如,dbo.IsReturnsBit(value) = 1。 - Darren Griffith
唯一的缺点是它不太用户友好。例如,我正在显示一个 SQL 表格的数据网格,并希望用户能够看到/编辑真或假,而不是 1 或 0。 - Charles Clayton
1
@crclayton 您可以创建一个关联的计算列,返回1表示true,返回0表示false。其他选项是使用报表转换。当然,这假定您的典型用户不是习惯于0/1系统的程序员。 - CSS

107

您可能想使用BIT数据类型,可能将其设置为 NOT NULL

引用MSDN文章

bit (Transact-SQL)

一种整数数据类型,可取值为1、0或NULL。

SQL Server数据库引擎优化了位列的存储。如果一个表中有8个或更少的位列,则这些列将被存储为1个字节。如果有从9到16个位列,则这些列将被存储为2个字节,依此类推。

字符串值TRUE和FALSE可以转换为位值:TRUE转换为1,FALSE转换为0。


70

您正在寻找一个位(bit)。它可以存储1或0(或NULL)。

或者,您可以使用字符串'true''false'代替1或0,例如-

declare @b1 bit = 'false'
print @b1                    --prints 0

declare @b2 bit = 'true'
print @b2                    --prints 1

此外,任何非0值(无论是正数还是负数)都会被视为1(或在某些情况下转换为1)。

declare @i int = -42
print cast(@i as bit)    --will print 1, because @i is not 0

请注意,SQL Server 使用三值逻辑(truefalseNULL),因为 NULLbit 数据类型的可能值。以下是相关的真值表 -

enter image description here

关于三值逻辑的更多信息-

SQL Server中三值逻辑的示例

http://www.firstsql.com/idefend3.htm

https://www.simple-talk.com/sql/learn-sql-server/sql-and-the-snare-of-three-valued-logic/


truefalse不是非零值吗? - Malachi
@Malachi 零被视为假,非零值被视为真。但是,真被计算为1,假被计算为0。例如,声明 @b bit = -9;如果 @b = 1 print 'pass' --注意如何将位设置为-9,但隐式转换为1(即“true”),并通过if测试。 - John Smith
值得注意的是,使用此方法会遇到额外的开销,因为SQL将分别将您的“true”或“false”转换为1或0。 - Nathaniel Bendinsky
@NathanielBendinsky 是的,如果涉及到任何强制转换,就会有开销(不仅在这种情况下...)。我只是想指出可以直接使用True / False。但是,确实更有效率的方法是使用1和0。 - John Smith

50

SQL Server中有布尔数据类型。它的值可以是TRUE, FALSEUNKNOWN。然而,布尔数据类型只是包含一些比较运算符(如=<><>=)或逻辑运算符(如ANDORINEXISTS)的布尔表达式的结果。布尔表达式仅允许出现在少数几个地方,包括WHERE子句、HAVING子句、CASE表达式WHEN子句或IFWHILE流程控制语句的谓词中。

对于其他用途,包括表中列的数据类型,布尔值不被允许。对于这些其他用途,首选BIT数据类型。它的行为类似于缩小范围的INTEGER,只允许值01NULL,除非通过NOT NULL列约束或CHECK约束进一步限制。
要在布尔表达式中使用BIT列,需要使用比较运算符进行比较,例如=<>IS NULL。例如:
SELECT
    a.answer_body
FROM answers AS a
WHERE a.is_accepted = 0;

从格式化的角度来看,bit值通常在客户端软件中显示为01。当需要更用户友好的格式,并且它不能在数据库前的应用程序层处理时,可以使用CASE表达式进行“即时”转换,例如。

SELECT
    a.answer_body,
    CASE a.is_accepted WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS is_accepted
FROM answers AS a;

将布尔值存储为字符数据类型,例如 char(1)varchar(5),也是可能的,但这样做不够清晰,需要更多的存储/网络开销,并且需要在每个列上使用 CHECK 约束来限制非法值。
参考 answers 表的模式类似于:
CREATE TABLE answers (
    ...,
    answer_body nvarchar(MAX) NOT NULL,
    is_accepted bit NOT NULL DEFAULT (0)
);

2
位(bit)并不是布尔(Boolean)的等价物,因为你不能将布尔表达式分配(assign)给位列(column)。真正的支持应该处理逻辑运算符(logical operators)直接分配(assign)到位域(bit field),例如 x = y AND z。我最喜欢你的答案,因为你明确指出了这一点。 - JohnOpincar

10
你可以在 SQL Server 中使用 Bit 数据类型来存储布尔值数据。

8

SQL Server 使用 Bit 数据类型。


8
使用Bit数据类型。在本地T-SQL中处理它时,它具有值1和0。

2

使用 BIT 数据类型表示布尔数据。一个 BIT 字段的值可以是 1、0 或 NULL。

create table <tablename> (
    <columnName> bit
)

除非你想要一个三元布尔值,否则应该添加 NOT NULL DEFAULT 0,如下所示:
create table <tablename> (
    <columnName> bit not null default 0
)

1

我在SQL Server中使用TINYINT(1)数据类型来存储布尔值,虽然BIT更有效。


2
"BIT非常有效", 那么为什么要使用TINYINT(1)呢? - Caltor
TINYINT 只存储 1 字节,您可以在此处查看更多信息:https://learn.microsoft.com/en-us/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql?view=sql-server-2017 - Bipul Roy
但是Bit更好,因为SQL可以将多达8个Bit打包在一个字节中。 - Caltor
2
我发现在MySQL中,TINYINT(1)的效果更好,因为BIT是一个二进制位值,可以表示1个或多个位,而不是一个序数。这就是为什么他们将BOOL作为TINYINT(1)的别名。对于MS-SQL/TSQL,BIT通常也很好用。如果他们费心将多个位打包在一起,我会非常惊讶的。 - AndrewWhalan
1
TINYINT允许在SQL Server中使用'+'表示OR,'*'表示AND,我想有时可能会很有用。 - High Plains Grifter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接