Eva*_*oll 6 mysql mariadb mariadb-10.1 bit-manipulation
我的另一个问题仅与&
字符串类型有关。这个问题是关于用B''
或构造的二进制字符串文字X''
。
MariaDB 支持二进制和十六进制文字,
SELECT X'01', B'00000001', X'01' = B'00000001';
| X'01' | B'00000001' | X'01' = B'00000001' |
+-------+-------------+---------------------+
| X | X | 1 |
* Using `X` because StackExchange strips the non-printable character.
Run Code Online (Sandbox Code Playgroud)
然而,有趣的是,当我通过二元运算符传递它们时,它们并不相同
SELECT X'01' & B'00000001', X'01' & X'01', B'00000001' & B'00000001';
| X'01' & B'00000001' | X'01' & X'01' | B'00000001' & B'00000001' |
+---------------------+---------------+---------------------------+
| 0 | 0 | 1 |
Run Code Online (Sandbox Code Playgroud)
所以,如果他们是位字符串处理它没有任何意义(因为其结果应该是1
,如果他们作为字符串处理,因为实际的字符串,它是没有意义的,其实(BIT-AND
ED) &
,以1
这表明它们不会“在所有上下文中都表现为字符串”。
SELECT X'01' & B'00000001', '01' & '00000001';
+---------------------+-------------------+
| X'01' & B'00000001' | '01' & '00000001' |
+---------------------+-------------------+
| 0 | 1 |
+---------------------+-------------------+
Run Code Online (Sandbox Code Playgroud)
我在十六进制文字的文档中看到了这一点,
对于十六进制文字,位操作被视为数字上下文,但在 MySQL 8.0 及更高版本中,位操作允许数字或二进制字符串参数。要为十六进制文字显式指定二进制字符串上下文,请
_binary
对至少一个参数使用介绍器。
通常,十六进制文字被解释为二进制字符串,其中每对数字代表一个字符。在数字上下文中使用时,它们被解释为整数。(见下面的例子)。在任何情况下,十六进制文字都不能是十进制数。
但这似乎仍然没有减少它,如果有的话它会使情况变得更糟(现在没有&
返回非 0.
SELECT _binary X'01' & _binary B'00000001', _binary X'01' & _binary X'01', _binary B'00000001' & _binary B'00000001';
| _binary X'01' & _binary B'00000001' | _binary X'01' & _binary X'01' | _binary B'00000001' & _binary B'00000001' |
+-------------------------------------+-------------------------------+-------------------------------------------+
| 0 | 0 | 0 |
Run Code Online (Sandbox Code Playgroud)
即使是明确的演员也是错误的,
SELECT CAST(_binary X'01' AS BINARY(8)) & CAST(_binary B'0000001' AS BINARY(8));
| CAST(_binary X'01' AS BINARY(8)) & CAST(_binary B'0000001' AS BINARY(8)) |
+--------------------------------------------------------------------------+
| 0 |
Run Code Online (Sandbox Code Playgroud)
另一个奇怪的事情是,当它们存储在桌子上时,它们的行为是不同的,例如,
CREATE TABLE g
AS
SELECT b'00000001' AS value, b'00000001' = 0 AS isequal;
SELECT value, value=0, isequal AS wasequal
FROM g;
+-------+---------+----------+
| value | value=0 | wasequal |
+-------+---------+----------+
| | 1 | 0 |
+-------+---------+----------+
Run Code Online (Sandbox Code Playgroud)
为什么二进制文字和十六进制文字的行为不同,它们的行为是什么?
这是自版本 10.0.3 和 5.5.31 以来 MariaDB 中的预期行为。看起来您正在 MariaDB 中运行查询,但正在阅读 MySQL 文档。这些是相似但不同的 RDBMS。
根据关于十六进制文字的 MariaDB 文档:
前两个语法;X'value' 和 x'value,遵循 SQL 标准,并且自 MariaDB 10.0.3 和 MariaDB 5.5.31(修复MDEV-4489)以来,在 MariaDB 的所有上下文中都表现为字符串。后一种语法 0xvalue 是十六进制混合的 MySQL/MariaDB 扩展,根据上下文表现为字符串或数字。MySQL 对所有语法都一视同仁,因此 MariaDB 和 MySQL 中可能会有不同的结果(见下文)。
您的示例中的查询将发出警告,例如:
| 警告| 1292 | 1292 截断了不正确的 INTEGER 值:'\x01' |
因此,您可以通过使用非标准 0xvalue 语法来获得所需的行为:
SELECT 0x01 & B'00000001', 0x01 & 0x01, B'00000001' & B'00000001';
Run Code Online (Sandbox Code Playgroud)
这使:
+--------------------+-------------+---------------------------+
| 0x01 & B'00000001' | 0x01 & 0x01 | B'00000001' & B'00000001' |
+--------------------+-------------+---------------------------+
| 1 | 1 | 1 |
+--------------------+-------------+---------------------------+
Run Code Online (Sandbox Code Playgroud)