>我有一个表,其中包含可为空的列:
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
我插入一行名称设置为 NULL;
INSERT INTO some_table (id, name) VALUES (1, NULL);
Query OK, 1 row affected (0.02 sec)
SELECT * FROM some_table;
+------+------+
| id | name |
+------+------+
| 1 | NULL |
+------+------+
1 row in set (0.01 sec)
如果我将表的名称列更改为不可为空,它显然会将 NULL 转换为空字符串:
ALTER TABLE some_table CHANGE COLUMN name name VARCHAR(255) NOT NULL;
Query OK, 1 row affected, 1 warning (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 1
SELECT * FROM some_table;
+------+------+
| id | name |
+------+------+
| 1 | |
+------+------+
1 row in set (0.02 sec)
此时,我希望会引发异常,告诉我我的数据集中有 NULL,并且我无法将列名设置为 NOT NULL。
这是SQL/MariaDB中的可配置选项吗?为什么将 NULL 转换为空字符串?
更改表时会调用警告:
SHOW WARNINGS;
+---------+------+-------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------+
| Warning | 1265 | Data truncated for column 'name' at row 1 |
+---------+------+-------------------------------------------+
1 row in set (0.01 sec)
版本:
SELECT version();
+----------------+
| version() |
+----------------+
| 5.5.62-MariaDB |
+----------------+
1 row in set (0.02 sec)
显然,从ALTER TABLE
的文档来看,启用严格模式会阻止您的 alter 语句成功:
此转换可能会导致数据更改。例如,如果缩短字符串列,则值可能会被截断。若要防止操作在转换为新数据类型会导致数据丢失时成功,请在使用 ALTER TABLE 之前启用严格 SQL 模式。
从 MySQL 中启用严格模式的一种方法:
SET GLOBAL sql_mode='STRICT_TRANS_TABLES';
有关其他选项,请参阅此处。
在 Debian Buster 上使用 10.3.15-MariaDB-1,我无法重现该问题:
MariaDB [foo]> CREATE TABLE some_table(id int(11), name varchar(255));
Query OK, 0 rows affected (0.009 sec)
MariaDB [foo]> INSERT INTO some_table (id, name) VALUES (1, NULL);
Query OK, 1 row affected (0.003 sec)
MariaDB [foo]> SELECT * FROM some_table;
+------+------+
| id | name |
+------+------+
| 1 | NULL |
+------+------+
1 row in set (0.000 sec)
MariaDB [foo]> ALTER TABLE some_table CHANGE COLUMN name name VARCHAR(255) NOT NULL;
ERROR 1265 (01000): Data truncated for column 'name' at row 1
MariaDB [foo]> SELECT * FROM some_table;
+------+------+
| id | name |
+------+------+
| 1 | NULL |
+------+------+
1 row in set (0.000 sec)
MariaDB [foo]> SELECT version();
+-------------------+
| version() |
+-------------------+
| 10.3.15-MariaDB-1 |
+-------------------+
1 row in set (0.000 sec)
如果可能的话,我建议您更新MariaDB版本。对我来说,这似乎很古老。