MySQL − 在重複鍵上更新插入



MySQL 中的INSERT INTO 語句用於將新記錄插入到特定表中。

MySQL 在重複鍵上更新插入語句

當我們嘗試將新行插入具有唯一索引或主鍵的 MySQL 表列時,如果要插入的值已存在於列中,MySQL 將發出錯誤。 這是因為這些約束要求唯一值,不允許重複值。

但是,如果我們使用 MySQL 的ON DUPLICATE KEY UPDATE 子句與 INSERT INTO 語句一起使用,MySQL 將使用新值更新現有行,而不是顯示錯誤。

語法

以下是 MySQL 中 ON DUPLICATE KEY UPDATE 子句的基本語法:

INSERT INTO my_table (col1, col2, ...) 
VALUES (val1, val2), (val3, val4), ...
ON DUPLICATE KEY UPDATE <col1>=<val1>, <col2>=<val2>,...;

示例

首先,讓我們使用以下查詢建立一個名為CUSTOMERS的表:

CREATE TABLE CUSTOMERS (
   ID int NOT NULL,
   NAME varchar(20) NOT NULL,
   AGE int NOT NULL,
   ADDRESS char (25),
   SALARY decimal (18, 2),
   PRIMARY KEY (ID)
);

在這裡,我們使用 INSERT INTO 語句將一些記錄插入到上面建立的表中,如下所示:

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) VALUES 
(1, 'Ramesh', 32, 'Ahmedabad', 2000.00 ),
(2, 'Khilan', 25, 'Delhi', 1500.00 ),
(3, 'Kaushik', 23, 'Kota', 2000.00 );

執行以下查詢以顯示上面建立的 CUSTOMERS 表中存在的記錄:

SELECT * FROM CUSTOMERS;

以下是 CUSTOMERS 表中的記錄:

ID 姓名 年齡 地址 薪水
1 Ramesh 32 Ahmedabad 2000.00
2 Khilan 25 Delhi 1500.00
3 Kaushik 23 Kota 2000.00

在這裡,我們使用 INSERT INTO 語句將另一行插入到 CUSTOMERS 表中,其ID 值為3

INSERT INTO CUSTOMERS (ID, NAME, AGE, ADDRESS, SALARY) 
VALUES (3, 'Chaitali', 25, 'Mumbai', 6500.00);

結果,MySQL 將發出錯誤,因為我們正在插入重複的ID 值:

ERROR 1062 (23000): Duplicate entry '3' for key 'customers.PRIMARY'

我們可以避免上述錯誤並使用ON DUPLICATE KEY UPDATE 子句以及 INSERT INTO 語句更新現有行,如下所示:

INSERT INTO CUSTOMERS (ID, NAME, AGE, ADDRESS, SALARY) 
VALUES (3, 'Chaitali', 25, 'Mumbai', 6500.00)
ON DUPLICATE KEY UPDATE NAME = "Chaitali",
AGE = 25,
ADDRESS = "Mumbai",
SALARY = 6500.00;

輸出

正如我們在輸出中看到的,上面的查詢更新了 CUSTOMERS 表中的現有行。結果,它返回兩行受影響的行。

Query OK, 2 rows affected (0.01 sec)

驗證

執行以下查詢以驗證現有行是否已更新為新資訊:

SELECT * FROM CUSTOMERS;

正如我們在表中觀察到的第三行一樣,記錄已被更新。

ID 姓名 年齡 地址 薪水
1 Ramesh 32 Ahmedabad 2000.00
2 Khilan 25 Delhi 1500.00
3 Chaitali 25 Mumbai 6500.00

示例

在下面的查詢中,我們嘗試使用 INSERT INTO 語句以及 ON DUPLICATE KEY UPDATE 子句將新行插入到CUSTOMERS表中:

INSERT INTO CUSTOMERS (ID, NAME, AGE, ADDRESS, SALARY) 
VALUES (4, 'Hardik', 27, 'Bhopal', 8500.00)
ON DUPLICATE KEY UPDATE NAME = "Hardik",
AGE = 27,
ADDRESS = "Bhopal",
SALARY = 8500.00;

輸出

正如我們在輸出中看到的,插入新行時沒有發生衝突。結果,它返回一行受影響的行。

Query OK, 1 row affected (0.01 sec)

驗證

我們可以使用以下查詢驗證新行是否已插入到 CUSTOMERS 表中:

SELECT * FROM CUSTOMERS;

正如我們在下面的輸出中觀察到的那樣,新行已插入。

ID 姓名 年齡 地址 薪水
1 Ramesh 32 Ahmedabad 2000.00
2 Khilan 25 Delhi 1500.00
3 Chaitali 25 Mumbai 6500.00
4 Hardik 27 Bhopal 8500.00

一次性插入或更新多條記錄

在同時插入或更新 MySQL 中多條記錄時,每個列的值設定可能因具有衝突的記錄而異。

例如,如果我們嘗試插入四行新行,但第三行具有與現有記錄衝突的ID列,則我們很可能希望根據您對第三行的設想資料來更新現有行。

示例

在執行下一個操作之前,讓我們看一下更新後的 CUSTOMERS 表的記錄:

SELECT * FROM CUSTOMERS;

以下是更新後的 CUSTOMERS 表:

ID 姓名 年齡 地址 薪水
1 Ramesh 32 Ahmedabad 2000.00
2 Khilan 25 Delhi 1500.00
3 Chaitali 25 Mumbai 6500.00
4 Hardik 27 Bhopal 8500.00

以下查詢向 CUSTOMERS 表中新增兩行新行:

INSERT INTO CUSTOMERS (ID, NAME, AGE, ADDRESS, SALARY)
VALUES (5, "Komal", 22, "Hyderabad", 4500.00),
(4, "Kaushik", 23, "Kota", 2000.00)
ON DUPLICATE KEY UPDATE 
NAME = VALUES(NAME), 
AGE = VALUES(AGE), 
ADDRESS = VALUES(ADDRESS), 
SALARY = VALUES(SALARY);

輸出

正如我們在輸出中看到的,有兩行新行(ID 5 和 4)和一行更新的行(ID 4),其中它與現有行衝突(已經有一行 ID 為“4”的行)。

Query OK, 3 rows affected, 4 warnings (0.01 sec)
Records: 2  Duplicates: 1  Warnings: 4

驗證

執行以下查詢以驗證記錄是否已插入到 CUSTOMERS 表中。

SELECT * FROM CUSTOMERS;

如果我們檢視下面的“CUSTOMERS”表,我們可以看到兩行新行已按預期新增,並且衝突行的值已更新為新資訊。

ID 姓名 年齡 地址 薪水
1 Ramesh 32 Ahmedabad 2000.00
2 Khilan 25 Delhi 1500.00
3 Chaitali 25 Mumbai 6500.00
4 Kaushik 23 Kota 2000.00
5 Komal 22 Hyderabad 4500.00

客戶端程式

除了使用 MySQL 查詢在 MySQL 表中執行“在重複鍵上更新插入”查詢外,我們還可以使用客戶端程式對錶執行相同的操作。

語法

以下是各種程式語言中此操作的語法:

要在 MySQL 表中透過 PHP 程式更新重複行,我們使用 DUPLICATE KEY UPDATE 以及使用mysqli函式query()INSERT語句,如下所示:

$sql = "INSERT INTO my_table (column1, column2, ...) 
VALUES (value1, value2), (value3, value4), ... 
ON DUPLICATE KEY UPDATE
 column1 = value1,
 column2 = value2, ..."; 
$mysqli->query($sql);

要在 MySQL 表中透過 Node.js 程式更新重複行,我們使用 DUPLICATE KEY UPDATE 以及使用mysql2庫的query()函式的INSERT語句,如下所示:

sql = "INSERT INTO my_table (column1, column2, ...)
VALUES  (value1, value2), (value3, value4), ...
ON DUPLICATE KEY UPDATE
 column1 = value1,
 column2 = value2, ...";  
con.query(sql);

要在 MySQL 表中透過 Java 程式更新重複行,我們使用 DUPLICATE KEY UPDATE 以及使用JDBC函式executeUpdate()INSERT語句,如下所示:

String sql = "INSERT INTO my_table (column1, column2, ...) 
VALUES (value1, value2), (value3, value4), ... 
ON DUPLICATE KEY UPDATE
 column1 = value1,
 column2 = value2, ...";
statement.executeUpdate(sql);

要在 MySQL 表中透過 Python 程式更新重複行,我們使用 DUPLICATE KEY UPDATE 以及使用 MySQL Connector/Pythonexecute()函式的INSERT語句,如下所示:

  
insert_on_duplicate_key_update_query = "INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...) 
ON DUPLICATE KEY UPDATE 
column1 = VALUES(column1), column2 = VALUES(column2), ..."
cursorObj.execute(insert_on_duplicate_key_update_query) 

示例

以下是程式:

$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = 'password';
$dbname = 'TUTORIALS';
$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
if($mysqli->connect_errno ) {
   printf("Connect failed: %s
", $mysqli->connect_error); exit(); } //printf('Connected successfully.
'); $q = "SELECT * FROM tutorials_tbl"; if($res = $mysqli->query($q)){ printf("Select query executed successfully..!\n"); printf("The table 'tutorials_tbl' records before insert into duplicate key update query executed: \n"); while($r = mysqli_fetch_array($res)){ print_r ($r); } } $sql = "INSERT INTO tutorials_tbl(tutorial_id, tutorial_title, tutorial_author, submission_date) VALUES(2, 'PHP Tut', 'unknown2', '2023-08-12') ON DUPLICATE KEY UPDATE tutorial_author = 'New Author'"; if($result = $mysqli->query($sql)){ printf("Insert on Duplicate Key Update query executed successfully..! \n"); } $q = "SELECT * FROM tutorials_tbl"; if($res = $mysqli->query($q)){ printf("Select query executed successfully..!\n"); printf("The table 'tutorials_tbl' records after insert into duplicate key update query executed: \n"); while($r = mysqli_fetch_array($res)){ print_r ($r); } } if($mysqli->error){ printf("Failed..!" , $mysqli->error); } $mysqli->close();

輸出

獲得的輸出如下:

Select query executed successfully..!
The table 'tutorials_tbl' records before insert into duplicate key update query executed:
Array
(
    [0] => 1
    [tutorial_id] => 1
    [1] => Java Tutorial
    [tutorial_title] => Java Tutorial
    [2] => new_author
    [tutorial_author] => new_author
    [3] =>
    [submission_date] =>
)
Array
(
    [0] => 2
    [tutorial_id] => 2
    [1] => PHP Tut
    [tutorial_title] => PHP Tut
    [2] => unknown2
    [tutorial_author] => unknown2
    [3] => 2023-08-12
    [submission_date] => 2023-08-12
)
Insert on Duplicate Key Update query executed successfully..!
Select query executed successfully..!
The table 'tutorials_tbl' records after insert into duplicate key update query executed:
Array
(
    [0] => 1
    [tutorial_id] => 1
    [1] => Java Tutorial
    [tutorial_title] => Java Tutorial
    [2] => new_author
    [tutorial_author] => new_author
    [3] =>
    [submission_date] =>
)
Array
(
    [0] => 2
    [tutorial_id] => 2
    [1] => PHP Tut
    [tutorial_title] => PHP Tut
    [2] => New Author
    [tutorial_author] => New Author
    [3] => 2023-08-12
    [submission_date] => 2023-08-12
)  
var mysql = require('mysql2');
var con = mysql.createConnection({
    host: "localhost",
    user: "root",
    password: "Nr5a0204@123"
});

  //Connecting to MySQL
  con.connect(function (err) {
  if (err) throw err;
  console.log("Connected!");
  console.log("----------------------------------------");

  //Selecting a Database
  sql = "USE TUTORIALS"
  con.query(sql);

  //Creating Table
  sql = "CREATE TABLE Actors (ID int auto_increment,NAME varchar(20) NOT NULL,LATEST_FILM varchar(20),Primary Key (ID));"
  con.query(sql);

  sql= "INSERT INTO Actors (NAME, LATEST_FILM)VALUES ('Prabhas', 'Salaar'),('Ram Charan', 'Game changer'),('Allu Arjun', 'Pushpa2');"
  con.query(sql, function (err, result) {
      if (err) throw err;
      console.log(result);
      console.log("----------------------------------------");
  });

  sql = "SELECT * FROM Actors;"
  con.query(sql, function (err, result) {
    if (err) throw err;
    console.log(result);
    console.log("----------------------------------------");
  });

  sql = "INSERT INTO Actors (ID, NAME) VALUES (3, 'Fahad') ON DUPLICATE KEY UPDATE NAME = 'Fahad';"
  con.query(sql, function (err, result) {
    if (err) throw err;
    console.log(result);
    console.log("----------------------------------------");
  });

  sql = "SELECT * FROM Actors;"
  con.query(sql, function (err, result) {
    if (err) throw err;
    console.log(result);
  });
});    

輸出

產生的輸出如下:

Connected!
----------------------------------------
ResultSetHeader {
  fieldCount: 0,
  affectedRows: 3,
  insertId: 1,
  info: 'Records: 3  Duplicates: 0  Warnings: 0',
  serverStatus: 2,
  warningStatus: 0,
  changedRows: 0
}
----------------------------------------
[
  { ID: 1, NAME: 'Prabhas', LATEST_FILM: 'Salaar' },
  { ID: 2, NAME: 'Ram Charan', LATEST_FILM: 'Game changer' },
  { ID: 3, NAME: 'Allu Arjun', LATEST_FILM: 'Pushpa2' }
]
----------------------------------------
ResultSetHeader {
  fieldCount: 0,
  affectedRows: 2,
  insertId: 3,
  info: '',
  serverStatus: 2,
  warningStatus: 0,
  changedRows: 0
}
----------------------------------------
[
  { ID: 1, NAME: 'Prabhas', LATEST_FILM: 'Salaar' },
  { ID: 2, NAME: 'Ram Charan', LATEST_FILM: 'Game changer' },
  { ID: 3, NAME: 'Fahad', LATEST_FILM: 'Pushpa2' }
]    
public class InsertOnDuplicate {
  public static void main(String[] args) {
    String url = "jdbc:mysql://:3306/TUTORIALS";
    String user = "root";
    String password = "password";
    ResultSet rs;
    try {
      Class.forName("com.mysql.cj.jdbc.Driver");
            Connection con = DriverManager.getConnection(url, user, password);
            Statement st = con.createStatement();
            //System.out.println("Database connected successfully...!");
            String sql = "SELECT * FROM Actors";
            rs = st.executeQuery(sql);
            System.out.println("Table records before insert on duplicate key update: ");
            while(rs.next()) {
              String id = rs.getString("ID");
              String name = rs.getString("NAME");
              String latest_film = rs.getString("LATEST_FILM");
              System.out.println("Id: " + id + ", Name: " + name + ", Latest_film: " + latest_film);
            }
            //let use insert on duplicate update
            String sql1 = "INSERT INTO Actors (ID, NAME) VALUES (3, \"Ravi\") ON DUPLICATE KEY UPDATE NAME = \"Ravi\"";
            st.executeUpdate(sql1);
            System.out.println("Query insert on duplicate key update executed successfully....!");
            String sql2 = "SELECT * FROM Actors";
            rs = st.executeQuery(sql2);
            System.out.println("Table records after insert on duplicate update: ");
            while(rs.next()) {
              String id = rs.getString("ID");
              String name = rs.getString("NAME");
              String latest_film = rs.getString("LATEST_FILM");
              System.out.println("Id: " + id + ", Name: " + name + ", Latest_film: " + latest_film);
            }
            
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
}  

輸出

得到的輸出如下所示:

Table records before insert on duplicate key update: 
Id: 1, Name: Prabhas, Latest_film: Salaar
Id: 2, Name: Ram Charan, Latest_film: Game changer
Id: 3, Name: Allu Arjun, Latest_film: Pushpa2
Query insert on duplicate key update executed successfully....!
Table records after insert on duplicate update: 
Id: 1, Name: Prabhas, Latest_film: Salaar
Id: 2, Name: Ram Charan, Latest_film: Game changer
Id: 3, Name: Ravi, Latest_film: Pushpa2      
import mysql.connector
#establishing the connection
connection = mysql.connector.connect(
    host='localhost',
    user='root',
    password='password',
    database='tut'
)
cursorObj = connection.cursor()
insert_on_duplicate_key_update = "INSERT INTO tutorials_tbl (tutorial_id, tutorial_title, tutorial_author, submission_date) VALUES (7, 'New Tutorial', 'John Doe', '2023-07-25') ON DUPLICATE KEY UPDATE tutorial_title='Updated Tutorial', tutorial_author='Jane Smith', submission_date='2023-07-28'"
cursorObj.execute(insert_on_duplicate_key_update)
connection.commit()
print("INSERT on duplicate key update query executed successfully.")
cursorObj.close()
connection.close()

輸出

以下是上述程式碼的輸出:

INSERT on duplicate key update query executed successfully.
廣告