mysql - 如果未在 NOT NULL 枚举列上指定值,如何使 MariaDB 产生错误?

标签 mysql sql enums foreign-keys mariadb

问题总结

对于 MariaDB,如果您不指定具有 NOT NULL 约束的列,则插入语句会产生错误。但是,如果该列的数据类型为 ENUM,则使用隐式默认值(列表中的第一个),并且插入不会产生错误。我想得到一个错误。

细节/我尝试了什么

数字数据类型错误

在一个带有 NOT NULL 约束的数字列的表上,我确实收到了预期的错误

create table test_number (
    name VARCHAR(40),
    num tinyint(1) not null
);

insert into test_number (name, num) values ('small',null); # sanity check
insert into test_number (name) values ('small');
#Response: Error Code: 1364. Field 'num' doesn't have a default value

枚举数据类型没有错误

在带有 NOT NULL 约束的 ENUM 列的表上我没有收到错误

create table test_enum (
    name VARCHAR(40),
    size ENUM('x-small', 'small', 'medium', 'large', 'x-large') not null
);

insert into test_enum (name, size) values ('small',null); # sanity check
#Response: Error Code: 1048. Column 'size' cannot be null
insert into test_enum (name, size) values ('small',default(size)); # sanity check 2
#Response: Error Code: 1364. Field 'size' doesn't have a default value

但是下面的insert语句处理成功

insert into test_enum (name) values ('small');
select * from test_enum;
|#|name |size   |
|1|small|x-small|

如您所见,使用了隐式默认值“x-small”,它是创建语句列表中的第一个。

数据库配置

我在 MariaDB >= 5.5 的多个版本上试过,上面的输出是用 10.5.5 生成的。

SHOW VARIABLES LIKE '%version%';
|version|10.5.5-MariaDB-1:10.5.5+maria~focal|

我确实对数据库使用了严格的 SQL_MODE

SELECT REPLACE(@@SQL_MODE, ',', '\n');
#|STRICT_ALL_TABLES|

期望的结果

上述成功插入实际上在我们的应用程序中隐式发生,每当我们添加一个枚举列而忘记在 DAO 层中适配相应的代码时。 我希望得到一个错误,这样 CI 中的现有测试就会失败。

最佳答案

欢迎来到论坛。

你不会喜欢我的解决方案,但我认为这可能是获得你想要的异常的唯一方法。

基于“如果一个 ENUM 列被声明为 NOT NULL,它的默认值是允许值列表的第一个元素”这一明显不可变的事实,那么您可以通过以下方式插入 null 得到一个错误

一个。添加一个虚拟 EMPTY STRING 值,例如""作为枚举字段中的第一个

定义触发器如下:

    CREATE TRIGGER `test_enum_BEFORE_INSERT` 
    BEFORE INSERT ON `test_enum` 
    FOR EACH ROW
    BEGIN
        IF new.size = "" THEN
            SIGNAL SQLSTATE '23000' SET MYSQL_ERRNO=1048, MESSAGE_TEXT='Column  "size" cannot be null';
        END IF;  
    END

枚举字段中的虚拟字符串实际上可以是任何东西,只要触发器测试它是什么。所以可以使用“Bad Value”,触发器的测试变为

IF new.size = "Bad Value" THEN...

SIGNAL 的触发将导致 INSERT 失败。

关于mysql - 如果未在 NOT NULL 枚举列上指定值,如何使 MariaDB 产生错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63392899/

相关文章:

java - 检索 Enum 的标签以形成列表

mysql - LEFT OUTER JOIN,按日期过滤

python - 为 python/Django 安装 MySQL

php - 为什么此SQL语句不起作用

sql - 如何检测存储过程是否已经存在

c++ - 具有 int 类型的枚举类的 printf 不适用于 clang

php - 向数据库插入值时删除记录

长 SQL 字符串中的 Python 变量

sql - 索引是否用于嵌套选择中的 'outer' 和 'inner' where 子句?

java - 为什么在 Enum hashCode() 中引用 Object hashCode() 实现,而不是 ordinal() 函数?