2014-09-20 62 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