2016-07-15 32 views
0

使用phpMyAdmin和MySQL v5.5.49考慮:MySQL的唯一約束遇事在CREATE TABLE隨後INSERT

CREATE TABLE op_sys (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    name VARCHAR(255) NOT NULL, 
    version VARCHAR(255) NOT NULL, 
    -- UNIQUE KEY name_version (name, version) 
    -- CONSTRAINT name_version UNIQUE (name, version) 
    -- UNIQUE(name, version) 
    -- CONSTRAINT UNIQUE(name, version) 
)ENGINE=InnoDB; 

我試着註釋掉嘗試的所有四個簡單INSERT INTO停止重複sys_op值「名稱「和」版本「。所有四個處理都沒有錯誤。

插入到:

INSERT INTO op_sys(name, version) 
VALUES ('ANDROID','ANDROID'); 

執行 「成功」。 ANDROID ANDROID現在是一排。我錯在哪裏或者我沒有意識到什麼步驟?我檢查了MySQL手冊和幾個不同的帖子,似乎說我正確地做了...謝謝。

回答

2

你似乎誤解了什麼UNIQUE KEY意味着:

唯一索引創建,使得該指數 所有的值必須是不同的約束。如果嘗試使用與現有行匹配的鍵值 添加新行,則會發生錯誤。對於所有引擎,UNIQUE 索引允許可以包含NULL的列的多個NULL值。

如果你的表有UNIQUE(name, version),那麼你可以做:

INSERT INTO op_sys(name, version) VALUES ('ANDROID','ANDROID'); 

但是,接下來你這樣做的時候,它會失敗,因爲表中已存在與同一對一個記錄(姓名,版本)與您要插入的記錄一樣。

爲了防止插入具有用於name和version`相同值的記錄,你可以使用一個trigger

CREATE TRIGGER different_values BEFORE INSERT ON op_sys 
FOR EACH ROW BEGIN 
DECLARE identical_values CONDITION FOR SQLSTATE '45000'; 
IF NEW.name = NEW.version THEN 
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Identical values for name and version'; 
END IF; 
END; 

它將每個INSERT之前表sys_op運行,如果nameversion領域保持相同的值,它會產生一個錯誤,插入將失敗。

返回的錯誤看起來像這樣:

ERROR 1644 (45000): Identical values for name and version 

文檔:
- CREATE INDEX
- CREATE TRIGGER
- SIGNAL

+0

謝謝,這正是我一直在尋找。乾杯! – Chris

2

多列唯一索引防止你有相同的2個值對於這兩個字段之間的記錄。這意味着,您不能有2條記錄,其中名稱和版本是'ANDROID','ANDROID'。但是,唯一索引不會阻止這些字段在單個行內具有相同的值。

您必須在應用程序級別實現此控件,您需要檢查2個字段值是否相同,如果是,則不要執行插入操作。

在數據庫層中,您可以在插入觸發器之前添加一個a,然後檢查2字段的值,並使用signal命令引發自定義錯誤消息。

但我有這樣的一種感覺。就好像你曾經問過這個問題,你不能做一個if()在PHP ...

+0

不,第一次。是的,在PHP方面很容易 - 只需在執行插入之前檢查該值是否在列中。我會探索觸發器,因爲這似乎是我錯過了。謝謝! – Chris