2014-09-20 69 views
0

MySQL服务器版本:5.6.17 我有两个表:澄清 - 默认外键约束 - InnoDB的

vatbands:

`vatbands_id` INT(11) UNSIGNED NOT NULL, 
`client_id` INT(11) UNSIGNED NOT NULL COMMENT 'Customer ID', 
`code` ENUM('A', 'B', 'C', 'D', 'E', 'F') NOT NULL, 
PRIMARY KEY (`vatbands_id`, `code`, `client_id`), 
INDEX `vatcode_vatbands` (`code` ASC, `client_id` ASC) 
ENGINE = InnoDB; 

1行中vatbands:

INSERT INTO `vatbands` (`client_id`, `code`) VALUES ('1', 'A'); 

项目:

`client_id` INT(11) UNSIGNED NOT NULL, 
`vatcode` ENUM('A', 'B', 'C', 'D', 'E', 'F') NOT NULL DEFAULT 'A', 
PRIMARY KEY (`item_id`, `client_id`), 
INDEX `vatcode_item` (`vatcode` ASC, `client_id` ASC), 
    CONSTRAINT `vatcode_item` 
    FOREIGN KEY (`vatcode` , `client_id`) 
ENGINE = InnoDB; 

插入到孩子(项目)表:

INSERT INTO `item` (`client_id`, `code`) VALUES ('1', ''); 

当我尝试插入到我的项目表而不指定vatcode我得到外键约束失败:

Cannot add or update a child row: a foreign key constraint fails (`mydb`.`item`, CONSTRAINT `vatcode_item` FOREIGN KEY (`vatcode`, `client_id`) REFERENCES `vatbands` (`code`, `client_id`) ON DELETE NO ACTION ON UPDATE NO ACTION) 

为什么这样做,我认为指定vatcode的默认值会允许它继续(只要该行存在)?

我已经检查了InnoDB的手册:

14.6.6 InnoDB和外键约束

InnoDB表的外键受到 以下条件引用操作:

虽然MySQL服务器允许SET DEFAULT,但由于InnoDB无效,因此 无效。

这是它失败的原因吗?

UPDATE:

如果我输入的值直接使用PHP:

INSERT INTO `item` (`client_id`, `code`) VALUES ('1', 'A'); 

约束成功按预期方式。

+1

'SET DEFAULT'指的是一个外键约束作用:'... ON DELETE SET DEFAULT'。 – rcdmk 2014-09-20 01:15:10

+0

请打开http://sqlfiddle.com/并在此处张贴链接。 – rcdmk 2014-09-20 01:16:33

+0

@rcdmk好的,这很有道理,谢谢。 – Edward 2014-09-20 01:16:58

回答

1

外键的SET DEFAULT子句与插入到子表无关。它声明如果在父表中引用的行被删除或更新,如何处理子表中的相关行。

示例:如果员工属于某个部门,并且该部门被删除,员工是否应该被解雇?还是应该将它们重新分配给其他“默认”部门?

我测试了你的例子,我发现它工作正常,但你必须至少指定父表中存在的client_id

mysql> insert into items (client_id) values (1); 
Query OK, 1 row affected (0.00 sec) 

我还注意到,您在密码匙(代码,client_id)上的密钥是非唯一密钥。它应该是一个子表的外键引用的主键或唯一键。事实上,当我使用MySQL 5.7里程碑版本进行测试时,我甚至无法创建表格items,因为在这方面显然,新版本的MySQL比旧版本更严格。所以我不得不让你的钥匙成为主钥匙。然后测试工作。

+0

嗨比尔,我已经指定client_d为'1 '在两个表中,都会更新我的问题。 – Edward 2014-09-20 01:54:07

+0

那么如何使它成为父表中的主键/唯一键呢? – 2014-09-20 08:38:21

+0

是的,它已经是父表中的主键,我会更新我的问题。 – Edward 2014-09-20 11:57:07

0

我可以得到这个工作的唯一方法是使用PHP插入一个默认值。

INSERT INTO `item` (`client_id`, `code`) VALUES ('1', 'A'); 

如果有人有更好的方法来解决这个问题,请不要犹豫,我会更喜欢纯粹的MySQL方法。

0

如果你使用:

INSERT INTO `item` (`client_id`, `code`) VALUES ('1', ''); 

您没有将空,但空字符串。

INSERT INTO `item` (`client_id`, `code`) VALUES ('1', NULL); 

将工作

+0

嗨Gervs,这是我第一次尝试!会再给它一次,欢呼。 – Edward 2014-09-20 12:25:32

+0

所以列被设置为NN,并且我得到了'列vatcode不能为空',所以我将其更改为可以为空的字段,现在它只是在该字段中插入'NULL' - 忽略DEFAULT值。 – Edward 2014-09-20 12:33:19