MYSQL错误1452 foriegn键约束失败

时间:2017-11-19 00:07:21

标签: php mysql database

我有一个完美的注册表单,但由于某种原因它没有添加到数据库。所以我在phpmyadmin中测试了这个查询,我发现了这个错误

查询:

INSERT INTO `EMTS`(`name`, `nickname`, `age`, `number`, `city`, `password`, `street`, `building`) 
VALUES ("Alice","Aa","21","414514151","New York","111","main","x")

我没有故意填写其他专栏。在其他数据库中,这不会导致任何问题

错误:

  

#1452 - 无法添加或更新子行:外键约束失败(mydbemts,CONSTRAINT fk_EMTS_shifts1 FOREIGN KEY(shifts_idshifts)REFERENCES {{ 1}}(shifts)ON DELETE NO ACTION ON UPDATE NO ACTION)

这是emts表:

idshifts

这是血型表:

CREATE TABLE IF NOT EXISTS mydb.EMTS(
idEMTS INT NOT NULL AUTO_INCREMENT,
name VARCHAR(45) NOT NULL,
nickname VARCHAR(45) NOT NULL,
age VARCHAR(45) NOT NULL,
number VARCHAR(45) NOT NULL,
email VARCHAR(45) NOT NULL,
city VARCHAR(255) NOT NULL,
password VARCHAR(45) NOT NULL,
shifts_idshifts INT(45) NOT NULL,
bloodtype_id INT NOT NULL,
street VARCHAR(45) NOT NULL,
building VARCHAR(45) NOT NULL,
  PRIMARY KEY (idEMTS),
  INDEX fk_EMTS_shifts1_idx(shifts_idshifts ASC),
  INDEX fk_EMTS_bloodtype1_idx(bloodtype_id ASC),
  UNIQUE INDEX nickname_UNIQUE(nickname ASC),
  CONSTRAINT fk_EMTS_shifts1
    FOREIGN KEY (shifts_idshifts)
    REFERENCES mydb.shifts(idshifts)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT fk_EMTS_bloodtype1
    FOREIGN KEY (bloodtype_id)
    REFERENCES mydb.bloodtype(id)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

这是轮班表:

CREATE TABLE IF NOT EXISTS mydb.bloodtype(
type INT NOT NULL,
id INT NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id))
ENGINE = InnoDB;

我没有得到什么问题?

1 个答案:

答案 0 :(得分:1)

我在我的本地MySQL实例上测试了你的查询。

如您所述,您没有为外键列提供值。但它们不是NULL列,并且它们没有默认值。所以MySQL填写值0。

我通过删除FOREIGN KEY约束并再次尝试INSERT来证明这一点:

mysql> INSERT INTO `EMTS`(`name`, `nickname`, `age`, `number`, `city`, `password`, `street`, `building`) 
    -> VALUES ("Alice","Aa","21","414514151","New York","111","main","x");
Query OK, 1 row affected, 3 warnings (0.02 sec)

mysql> show warnings;
+---------+------+------------------------------------------------------+
| Level   | Code | Message                                              |
+---------+------+------------------------------------------------------+
| Warning | 1364 | Field 'email' doesn't have a default value           |
| Warning | 1364 | Field 'shifts_idshifts' doesn't have a default value |
| Warning | 1364 | Field 'bloodtype_id' doesn't have a default value    |
+---------+------+------------------------------------------------------+
3 rows in set (0.01 sec)

mysql> select * from EMTS;
+--------+-------+----------+-----+-----------+-------+----------+----------+-----------------+--------------+--------+----------+
| idEMTS | name  | nickname | age | number    | email | city     | password | shifts_idshifts | bloodtype_id | street | building |
+--------+-------+----------+-----+-----------+-------+----------+----------+-----------------+--------------+--------+----------+
|      3 | Alice | Aa       | 21  | 414514151 |       | New York | 111      |               0 |            0 | main   | x        |
+--------+-------+----------+-----+-----------+-------+----------+----------+-----------------+--------------+--------+----------+

请注意,两个外键列的值都为0。

如果您不想为外键列提供值,请将它们设为可为空的列。存在NULL是可以的,它不会导致外键约束违规。 0是非NULL值,但在引用的表中不存在移位和血型。

https://dev.mysql.com/doc/refman/5.7/en/data-type-defaults.html说:

  

对于没有显式DEFAULT的NOT NULL列的数据输入   如果INSERT或REPLACE语句不包含任何值,则该子句   列,或UPDATE语句将列设置为NULL,MySQL处理   根据当时生效的SQL模式的列:

     
      
  • 如果启用了严格的SQL模式,则会发生事务错误   表和语句将回滚。对于非交易表,   发生错误,但如果第二行或后续行发生这种情况   多行语句,前面的行将是   插入

  •   
  • 如果未启用严格模式,MySQL会将列设置为隐式   列数据类型的默认值。

  •   

整数列的隐式默认值为0.

这对MySQL来说是一种奇怪的行为,导致许多开发人员感到困惑。如果列是NOT NULL,那么为什么它允许我们插入NULL,并默认为某些未指定的隐式默认值?这是违反直觉的。

因此,在较新版本的MySQL 5.7及更高版本中,严格模式已成为默认模式。您也可以自己设置严格模式:

mysql> SET sql_mode='strict_all_tables';

mysql> INSERT INTO `EMTS`(`name`, `nickname`, `age`, `number`, `city`, `password`, `street`, `building`) 
    -> VALUES ("Alice","Aa","21","414514151","New York","111","main","x");
ERROR 1364 (HY000): Field 'email' doesn't have a default value