You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止小数存入MySQL的pricePerNight列?解决CHECK约束无效问题

问题:阻止BIGINT列存入小数并触发错误

问题场景

现有Cabin表结构如下:

CREATE TABLE IF NOT EXISTS Cabin (
cabinID BIGINT AUTO_INCREMENT PRIMARY KEY,
cabinType VARCHAR(150) NOT NULL,
cabinDescription VARCHAR(255),
pricePerNight BIGINT NOT NULL,
pricePerWeek DECIMAL(10,2) NOT NULL,
photo VARCHAR(50)
);

执行以下插入语句时,pricePerNight字段传入了小数100.87,预期应该触发错误,但实际数据被自动取整为101存入数据库:

INSERT INTO Cabin (cabinType, cabinDescription, pricePerNight, pricePerWeek, photo)
VALUES ('test cabin 2', 'test cabin with invalid data', 100.87, 625, 'insertCabin1.jpg');

尝试添加CHECK约束后仍无法阻止该行为:

pricePerNight BIGINT(10) NOT NULL CHECK (pricePerNight >= 0 AND pricePerNight % 1 = 0)

需求:向pricePerNight插入小数时直接触发错误,而非自动取整保存。

解决方法

1. 启用MySQL严格模式

MySQL默认的宽松模式会自动转换不符合列类型的数据(如将小数转为整数)且不报错,需修改sql_mode启用严格模式:

  • 临时生效(重启MySQL后失效):
-- 全局生效
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
-- 当前会话生效
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
  • 永久生效:
    找到MySQL配置文件(如my.cnf或my.ini),在[mysqld]段添加:
sql_mode = STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

保存后重启MySQL服务即可。

启用严格模式后,向BIGINT列插入小数时会直接抛出Data truncation错误,阻止数据插入。

2. 用触发器校验(适配MySQL 8.0.16以下版本)

MySQL 8.0.16之前的版本不会强制执行CHECK约束,若使用旧版本,可通过触发器实现校验:

DELIMITER //
CREATE TRIGGER validate_pricePerNight_before_insert
BEFORE INSERT ON Cabin
FOR EACH ROW
BEGIN
    IF NEW.pricePerNight <> FLOOR(NEW.pricePerNight) THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'pricePerNight必须是整数';
    END IF;
END //
DELIMITER ;

该触发器会在插入数据前检查pricePerNight是否为整数,若不是则抛出错误,阻止插入。

内容的提问来源于stack exchange,提问作者web dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 14:21:12