【问题标题】:Trouble with using foreign keys in MYSQL database在 MYSQL 数据库中使用外键的问题
【发布时间】:2014-03-17 12:24:08
【问题描述】:

我在 mySQL 中使用外键时遇到问题。我看不到我所做的代码有任何问题,但是当我使用外键(公司表(用户 ID)将数据插入表中时它不起作用。抱歉含糊不清..第一次在这里问。

CREATE TABLE users 
(
userid INT(4) NOT NULL auto_increment,
username VARCHAR(30) NOT NULL,
email VARCHAR(32) NOT NULL,
password VARCHAR(32) NOT NULL,
companyName VARCHAR(32) NOT NULL,
address VARCHAR(30) NOT NULL,
PRIMARY KEY (userid)
) ENGINE=INNODB;





DROP TABLE IF EXISTS company;

CREATE TABLE company 
(
userid int(4) NOT NULL,
companyid INT(4) NOT NULL auto_increment,
companyName VARCHAR(32) NOT NULL,
address VARCHAR(30) NOT NULL,
telephone INT(20) NOT NULL,
email VARCHAR(30) NOT NULL,
textbody VARCHAR(1800) NOT NULL,
textbody2 VARCHAR(1500) NOT NULL,
PRIMARY KEY (companyid),
FOREIGN KEY (userid) REFERENCES users(userid)
) ENGINE=INNODB;

这是插入语句

INSERT INTO company (companyName, address, telephone, email, textbody, textbody2)VALUES 
('blaaah', 'Ireland', '12345', 'emailAddress', 'randomtext', 'morerandomtext');

这是错误

#1452 - Cannot add or update a child row: a foreign key constraint     fails(`users`.`company`, CONSTRAINT `company_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `    users` (`userid`))

【问题讨论】:

  • 它不起作用”不是可接受的错误描述。
  • 显示insert 和错误语句。
  • 哪里出错了!因为代码没有错误!
  • 您没有将 userid 的值插入到公司表中 - 这意味着您正在插入 NULL。但是 MySQL 试图变得聪明并且会默默地将 NULL 转换为 0 - 然后它失败了没有用户使用 userid = 0: sqlfiddle.com/#!2/4edfa/1 你需要为 userid 提供一个有效的(现有的)值插入时的列。

标签: mysql sql foreign-keys


【解决方案1】:

在将具有相同值的行插入users 表之前,您不能将具有特定userid 值的行插入到company 表中。这就是 FK 约束所强制执行的内容。

您在问题中显示的INSERT INTO company 语句未指定userid 的值。如果您使用外键约束,则必须指定该值,并且它必须是 users 表中存在的值之一。

您如何得出有效的userid 值?如果不了解您的业务逻辑,这很难准确回答:为什么每个 company 行必须正好引用一个 users 行?

解决问题的一种方法是在 INSERT users 行之后立即 INSERT company 行(立即!没有干预 INSERT 语句!)。在这种情况下,MySQL 函数 LAST_INSERT_ID() 将包含适当的自动增量值。

INSERT INTO users
       (username, email, password, company, address)
VALUES ('mickey', 'mickey@disney.com', 'ILuvMinnie', 'Walt Disney', 'Burbank');

INSERT INTO company 
       (userid, 
        companyName, address, telephone, 
        email, textbody, textbody2)
VALUES (LAST_INSERT_ID(),   /* from the previous insert */
       'Walt Disney', 'Burbank, CA', '203 555 1212',
       'info@disney.com', 'The Happiest Place on Earth.', 'morerandomtext');

【讨论】:

  • 我在用户表中有多个具有唯一用户 ID 的用户,所以这不是问题。
  • @user3375184 是的,这是问题所在,因为您已指定 company.userid 不能为空,并且外键进一步强制执行此约束。
  • 如果它在用户表中自动递增,我将如何将用户 ID 插入到公司表中?
【解决方案2】:

请试试这个代码:SQLFiddle

我在插入语句中使用电话号码格式和 last_insert_id()。

insert into users (username, email, password, companyName, address) 
values ('test', 'test@test.com', 'ghghb', 'test corp', 'test');

insert into company (userid, companyName, address, telephone, email, textbody, textbody2) 
values (last_insert_id(), 'test','test', 123456, 'test@test.com', 'test', 'test');

请查看公司表和check this link的约束声明。

我认为您在向公司插入新行时不会将 userId 添加到 INSERT 语句中。但是您应该添加一个现有的用户 ID。

基于 cmets:

如果您想插入没有用户 ID 的新公司行,请将表结构定义为:

CREATE TABLE company 
(
userid int(4),
companyid INT(4) NOT NULL auto_increment,
companyName VARCHAR(32) NOT NULL,
address VARCHAR(30) NOT NULL,
telephone INT(20) NOT NULL,
email VARCHAR(30) NOT NULL,
textbody VARCHAR(1800) NOT NULL,
textbody2 VARCHAR(1500) NOT NULL,
PRIMARY KEY (companyid),

) ENGINE=INNODB; 

在这种情况下,我没有定义foreign key。您可以插入带有或不带有 userId 的新公司行。

【讨论】:

  • 我在那里尝试过,当我插入公司表时出现此错误 #1242 - 子查询返回超过 1 行
  • 你应该使用last_insert_id() 而不是这样容易出错的子查询。
  • 插入语句有效,但前提是用户表中有一行。
  • 是的,这是正确的功能。如果要插入没有 userId 的公司行,请不要使用此外键。
  • 我尝试了更新的代码,我得到了这个错误“#1452 - 无法添加或更新子行:外键约束失败(users.company, CONSTRAINT company_ibfk_1 FOREIGN KEY (userid) 参考资料users (userid))"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
  • 2011-05-06
  • 1970-01-01
  • 2019-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多