HOWTO · MySQL

在 MySQL 表中使用重複鍵驗證插入值

本教程展示瞭如何在 MySQL 表中插入一個值,並正確驗證是否存在重複鍵/值。

傳統 SQL 的 INSERT 語句不會針對現有資料庫表執行其引數/值的輸入驗證。在插入過程中發現重複鍵時,有時會導致錯誤。

這在 MySQL 中通過 INSERT 的擴充套件與 ON DUPLICATE KEY UPDATEREPLACEIGNORE 等語句進行處理。

為了說明這些方法,讓我們建立一個名為 programming_languages 的示例資料庫。

-- Here goes the definition of the database
CREATE DATABASE programming_languages;
USE programming_languages;

-- Creating a table
CREATE TABLE Details(
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(25) UNIQUE,    -- Making name column unique 
    year_released VARCHAR (5),
    PRIMARY KEY(id)
    );

輸出:

20:22:03	CREATE DATABASE programming_languages	1 row(s) affected	0.219 sec
20:22:03	USE programming_languages	0 row(s) affected	0.000 sec
20:22:03	CREATE TABLE Details(id INT NOT NULL AUTO_INCREMENT, name VARCHAR(25) UNIQUE,     year_released VARCHAR (5),PRIMARY KEY(id)) 0 row(s) affected	0.625 sec

現在,詳細資訊表將填充如下值。

-- Names of popular programming languages and their release year
INSERT INTO Details (name, year_released) VALUES ('python', 1991),('c++', 1985),('Java', 1995);

SELECT * FROM Details ORDER BY id;    -- Previewing table

輸出:

id	name	year_released
1	python	1991
2	c++		1985
3	Java	1995

-----------------------------------------------------------------------------------------
20:23:24	INSERT INTO Details (name, year_released) VALUES ('python', 1991),('c++', 	     1985),('Java',1995) 3 row(s) affected Records: 3 Duplicates: 0 Warnings: 0	0.109 sec

20:23:24	SELECT * FROM Details ORDER BY id LIMIT 0, 1000	3 row(s) returned 0.000 sec /     0.000 sec

我們嘗試在表中插入一個名為 python 的行。正如預期的那樣,此操作會導致錯誤。

-- Trying to insert a new value
INSERT INTO Details (name, year_released) VALUES ('python', 1992)

輸出:

20:27:31	INSERT INTO Details (name, year_released) VALUES ('python',1992) Error Code:     1062. Duplicate entry 'python' for key 'details.name' 0.046 sec

使用 ON DUPLICATE KEY 更新方法在具有重複鍵驗證的 MySQL 表中插入值

此方法要麼插入新值(如果表中不存在),要麼更新現有行。因此,如果一行包含與新插入相同的資料,MySQL 不會進行任何更改。但是,如果其資料與插入查詢不同,它會更新該行。如果該行不存在,則插入該行。

INSERT INTO Details (name, year_released) VALUES ('python', 1992) as V ON DUPLICATE KEY UPDATE name = V.name, year_released = V.year_released;

SELECT * FROM Details ORDER BY id;   -- Checking the output

輸出:

id	name	year_released
1	python	1992
2	c++		1985
3	Java	1995

-----------------------------------------------------------------------------------------
20:47:35	INSERT INTO Details (name, year_released) VALUES ('python', 1992) as V ON         DUPLICATE KEY UPDATE name = V.name, year_released = V.year_released 2 row(s) affected     0.172 sec

20:49:23	SELECT * FROM Details ORDER BY id LIMIT 0, 1000	3 row(s) returned	0.000 sec     / 0.000 sec

從輸出中觀察到,year_released 列已針對 python 進行了更新,並且日誌表明兩 (2) 行受到影響(典型的行更新操作)。可以參考此擴充套件的官方參考以獲取更多選項。

使用 REPLACE 方法在具有重複鍵驗證的 MySQL 表中插入值

謹慎使用此方法!與之前的擴充套件不同,它刪除行並插入包含所需資料的新行。雖然這可能看起來是良性的,但如果在操作期間刪除了行的唯一關係,則可能會出現問題。

REPLACE INTO Details (name, year_released) VALUES ('python', 1993);
SELECT * FROM Details ORDER BY id;

輸出:

id	name	year_released
2	c++		1985
3	Java	1995
7	python	1993
-----------------------------------------------------------------------------------------
20:56:48	REPLACE INTO Details (name, year_released) VALUES ('python', 1993) 2 row(s)       affected 0.093 sec

現在,觀察 Insert 操作是否執行。但是,id 已更改(由於刪除和插入)。建議檢視此擴充套件的官方參考以確定安全使用和額外選項。

使用 IGNORE 方法在具有重複鍵驗證的 MySQL 表中插入值

IGNORE 方法對具有 duplicate keys 的行沒有任何作用。但是,它不會為 INSERT 操作引發錯誤。此方法可以處理不允許更新並且不需要引發異常/錯誤的情況。

INSERT IGNORE INTO Details (name, year_released) VALUES ('python', 1991);
SELECT * FROM Details ORDER BY id;

輸出:

id	name	year_released
2	c++		1985
3	Java	1995
7	python	1993
-----------------------------------------------------------------------------------------
21:29:44	INSERT IGNORE INTO Details (name, year_released) VALUES ('python', 1991) 0 	     row(s) affected, 1 warning(s): 1062 Duplicate entry 'python' for key 'details.name'	0.157 sec

正如預期的那樣,MySQL 不會引發任何錯誤。但是,該表保持不變。