MySQL 布尔值和存储过程

问题描述

我正在尝试通过 NodeJS 的存储过程在 MysqL 表中保存一些布尔值,并使用 MysqL2 执行它。

重要提示:我做了 SET @@global.sql_mode= ''; 来禁用严格模式。

假设我有这张桌子

DROP TABLE IF EXISTS `test_table`;
CREATE TABLE IF NOT EXISTS `test_table` (
`id` INT(11) NOT NULL AUTO_INCREMENT,`booleanField` BOOLEAN,PRIMARY KEY (`id`)
);

我想添加一个带有 { someBoolean: true } 的新行:

DROP PROCEDURE IF EXISTS test_procedure;
DELIMITER $$

CREATE PROCEDURE test_procedure(
    IN DATA JSON
)

BEGIN

  SET @someBoolean      = JSON_UNQUOTE(JSON_EXTRACT(DATA,'$.someBoolean'));

  INSERT INTO test_table (
    booleanField
  ) VALUES (
    @someBoolean
  );

  SELECT 
    @someBoolean AS receivedValue,id,booleanField
  FROM test_table;


END $$
DELIMITER ;

然后我执行它:

CALL test_procedure('{"someBoolean": true}');

这个结果是一个新行,有一些有趣的结果:

MysqL 终端客户端中运行所有这些代码,我收到:

+---------------+----+--------------+
| receivedValue | id | booleanField |
+---------------+----+--------------+
| true          |  1 |            0 |
+---------------+----+--------------+

因此即使接收到的值为 true,布尔字段也设置为 0

我可以检查 @someBoolean 是否为字符串 "true",并将其设置为 TRUE 等。

DROP PROCEDURE IF EXISTS test_procedure;
DELIMITER $$

CREATE PROCEDURE test_procedure(
    IN DATA JSON
)

BEGIN
  DECLARE CASTED_Vote INT; -- NEW
  SET @someBoolean      = JSON_UNQUOTE(JSON_EXTRACT(DATA,'$.someBoolean'));

  -- NEW
  IF      @someBoolean = "true"  THEN SET  CASTED_Vote = 1;
  ELSEIF  @someBoolean = "false" THEN SET  CASTED_Vote = 0;
  ELSE SET                          CASTED_Vote = NULL;
  END IF;
  -- END NEW

  INSERT INTO test_table (
    booleanField
  ) VALUES (
    CASTED_Vote
  );

  SELECT 
    CASTED_Vote,-- NEW
    @someBoolean AS receivedValue,booleanField
  FROM test_table;


END $$
DELIMITER ;

再次执行...

CALL test_procedure('{"someBoolean": true}');

瞧:

+-------------+---------------+----+--------------+
| CASTED_Vote | receivedValue | id | booleanField |
+-------------+---------------+----+--------------+
|           1 | true          |  1 |            1 |
+-------------+---------------+----+--------------+

但这意味着我必须在所有查询中一遍又一遍地做同样的事情。 我做错了什么?我错过了什么吗?

解决方法

CREATE PROCEDURE test_procedure(
    IN DATA JSON
)

BEGIN

  SET @someBoolean      = JSON_UNQUOTE(JSON_EXTRACT(DATA,'$.someBoolean'));

  INSERT INTO test_table (
    booleanField
  ) VALUES (
    @someBoolean = 'true'
  );

  SELECT 
    @someBoolean AS receivedValue,id,booleanField
  FROM test_table;


END

CREATE PROCEDURE test_procedure(
    IN DATA JSON
)

BEGIN

  SET @someBoolean := JSON_UNQUOTE(JSON_EXTRACT(DATA,'$.someBoolean')) = 'true';

  INSERT INTO test_table (
    booleanField
  ) VALUES (
    @someBoolean
  );

  SELECT 
    @someBoolean AS receivedValue,booleanField
  FROM test_table;


END

fiddle


如果我想传递null怎么办? CALL test_procedure('{"someBoolean": "null"}'); – 埃米尔 C.

SET @someBoolean := CASE JSON_UNQUOTE(JSON_EXTRACT(DATA,'$.someBoolean'))
                    WHEN 'true' THEN 1
                    WHEN 'false' THEN 0
                    END;

'true''false' 之外的任何值(包括参数缺失)都将被视为(当然也被赋值)为 NULL

fiddle