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://127.0.0.1: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.
广告