任何人都可以帮助我理解MySQL(5.7.19)中BIT(64)列的以下问题。
这个简单的例子工作正常,并从临时表中返回记录:
CREATE TEMPORARY TABLE test (v bit(64));
INSERT INTO test values (b'111');
SELECT * FROM test WHERE v = b'111';
-- Returns the record as expected
当使用列的所有64位时,它不再起作用:
CREATE TEMPORARY TABLE test (v bit(64));
INSERT INTO test values (b'1111111111111111111111111111111111111111111111111111111111111111');
SELECT * FROM test WHERE v = b'1111111111111111111111111111111111111111111111111111111111111111';
-- Does NOT return the record
仅在使用64位值时才会发生这种情况。但我希望这是可能的。
任何人都可以向我解释这个吗?
请不要回应,建议我不要使用BIT专栏。我正在研究一个能够处理MySQL所有数据类型的数据库工具。
答案 0 :(得分:0)
位以二进制形式返回,因此要显示它们,要么添加0,要么使用HEX,OCT或BIN等函数转换它们https://mariadb.com/kb/en/library/bit/或结果集中的位值作为二进制值返回,可能表现不佳。要将位值转换为可打印格式,请在数字上下文中使用它或使用转换函数,如BIN()或HEX()。转换后的值中不显示高位0位数。 https://dev.mysql.com/doc/refman/8.0/en/bit-value-literals.html
答案 1 :(得分:0)
问题似乎是,WHERE子句中的值b'11..11'
被认为是SIGNED BIGINT
,-1
并且与表中的值进行比较成为UNSIGNED BIGINT
,18446744073709551615
。当64位中的第一位为1
时,这始终是个问题。恕我直言这是一个错误或设计缺陷,因为如果在INSERT语句中使用了相同的表达式(至少在这种情况下),我希望WHERE子句中的表达式匹配一行。
一种解决方法是将值转换为UNSIGNED
:
SELECT *
FROM test
WHERE v = CAST(b'1111111111111111111111111111111111111111111111111111111111111111' as UNSIGNED);
或(如果您的应用语言支持)将其转换为long uint
或decimal
:
SELECT * FROM test WHERE v = 18446744073709551615;