Hướng dẫn mysql replace not working - mysql thay thế không hoạt động

13.2.9 & nbsp; thay thế câu lệnh

REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    { {VALUES | VALUE} (value_list) [, (value_list)] ...
      |
      VALUES row_constructor_list
    }

REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    SET assignment_list

REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    {SELECT ... | TABLE table_name}

value:
    {expr | DEFAULT}

value_list:
    value [, value] ...

row_constructor_list:
    ROW(value_list)[, ROW(value_list)][, ...]

assignment:
    col_name = value

assignment_list:
    assignment [, assignment] ...

REPLACE hoạt động chính xác giống như INSERT, ngoại trừ nếu một hàng cũ trong bảng có cùng giá trị với hàng mới cho chỉ số PRIMARY KEY hoặc UNIQUE, hàng cũ sẽ bị xóa trước khi hàng mới được chèn. Xem Phần & NBSP; 13.2.6, Tuyên bố chèn.

REPLACE là tiện ích mở rộng MySQL cho tiêu chuẩn SQL. Nó chèn, hoặc xóa và chèn. Đối với một tiện ích mở rộng MySQL khác sang SQL tiêu chuẩn, đó là chèn hoặc cập nhật phần xem Phần & NBSP; 13.2.6.2, Chèn chèn ... trên câu lệnh cập nhật khóa trùng lặp.deletes and inserts. For another MySQL extension to standard SQL—that either inserts or updates—see Section 13.2.6.2, “INSERT ... ON DUPLICATE KEY UPDATE Statement”.

CREATE TABLE test (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);
0 Chèn và thay thế đã được không dùng nữa trong MySQL 5.6. Trong MySQL 8.0,
CREATE TABLE test (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);
0 không được hỗ trợ. Máy chủ nhận ra nhưng bỏ qua từ khóa
CREATE TABLE test (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);
0, xử lý việc thay thế dưới dạng thay thế không điều trị và tạo cảnh báo
CREATE TABLE test (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);
3: Thay thế chậm không còn được hỗ trợ. Tuyên bố đã được chuyển đổi để thay thế. Từ khóa
CREATE TABLE test (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);
0 được lên lịch để loại bỏ trong một bản phát hành trong tương lai. phóng thích.REPLACE DELAYED is no longer supported. The statement was converted to REPLACE. The
CREATE TABLE test (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);
0 keyword is scheduled for removal in a future release. release.

Ghi chú

REPLACE chỉ có ý nghĩa nếu một bảng có chỉ mục PRIMARY KEY hoặc UNIQUE. Mặt khác, nó trở nên tương đương với INSERT, bởi vì không có chỉ số nào được sử dụng để xác định xem một hàng mới có sao chép khác hay không.

Các giá trị cho tất cả các cột được lấy từ các giá trị được chỉ định trong câu lệnh REPLACE. Bất kỳ cột bị thiếu nào được đặt thành các giá trị mặc định của chúng, giống như xảy ra đối với INSERT. Bạn không thể tham khảo các giá trị từ hàng hiện tại và sử dụng chúng trong hàng mới. Nếu bạn sử dụng một gán, chẳng hạn như

mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)
1 =
mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)
2 + 1, tham chiếu đến tên cột ở phía bên phải được coi là mặc định (____ 22), do đó, việc gán tương đương với
mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)
1 = mặc định (________ 22) + 1.DEFAULT(
mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)
2)
, so the assignment is equivalent to
mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)
1 = DEFAULT(
mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)
2) + 1.

Trong MySQL 8.0.19 trở lên, bạn có thể chỉ định các giá trị cột mà REPLACE cố gắng chèn bằng

mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)
7.

Để sử dụng REPLACE, bạn phải có cả đặc quyền INSERT

CREATE TABLE test2 (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id, ts)
);
0 cho bảng.

Nếu một cột được tạo được thay thế rõ ràng, giá trị được phép duy nhất là

CREATE TABLE test2 (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id, ts)
);
1. Để biết thông tin về các cột được tạo, xem Phần & NBSP; 13.1.20.8, Bảng Tạo bảng và các cột được tạo.

REPLACE Hỗ trợ lựa chọn phân vùng rõ ràng bằng mệnh đề

CREATE TABLE test2 (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id, ts)
);
3 với danh sách các tên phân tách dấu phẩy của các phân vùng, phụ hoặc cả hai. Như với INSERT, nếu không thể chèn hàng mới vào bất kỳ phân vùng hoặc phân vùng nào, câu lệnh REPLACE không thành công với lỗi tìm thấy một hàng không khớp với bộ phân vùng đã cho. Để biết thêm thông tin và ví dụ, xem Phần & NBSP; 24.5, Lựa chọn phân vùng.Found a row not matching the given partition set. For more information and examples, see Section 24.5, “Partition Selection”.

Tuyên bố REPLACE trả về số lượng để chỉ ra số lượng hàng bị ảnh hưởng. Đây là tổng của các hàng bị xóa và chèn. Nếu số đếm là 1 cho một hàng REPLACE, một hàng đã được chèn và không có hàng nào bị xóa. Nếu số lượng lớn hơn 1, một hoặc nhiều hàng cũ đã bị xóa trước khi hàng mới được chèn. Một hàng có thể thay thế nhiều hơn một hàng cũ nếu bảng chứa nhiều chỉ mục duy nhất và hàng mới sao chép các giá trị cho các hàng cũ khác nhau trong các chỉ mục duy nhất khác nhau.

Số lượng hàng bị ảnh hưởng giúp bạn dễ dàng xác định xem REPLACE chỉ thêm một hàng hay liệu nó cũng thay thế bất kỳ hàng nào: Kiểm tra xem số đếm là 1 (thêm) hoặc lớn hơn (thay thế).

Nếu bạn đang sử dụng API C, số lượng hàng bị ảnh hưởng có thể thu được bằng cách sử dụng hàm

CREATE TABLE test2 (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id, ts)
);
9.

Bạn không thể thay thế vào một bảng và chọn từ cùng một bảng trong một truy vấn con.

MySQL sử dụng thuật toán sau cho REPLACE (và

mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.05 sec)

mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 1 row affected (0.06 sec)

mysql> SELECT * FROM test2;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | Old  | 2014-08-20 18:47:00 |
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
2 rows in set (0.00 sec)
1):

  1. Cố gắng chèn hàng mới vào bảng

  2. Mặc dù việc chèn không thành công do lỗi chính lặp lại đối với khóa chính hoặc chỉ mục duy nhất:

    1. Xóa khỏi bảng Hàng xung đột có giá trị khóa trùng lặp

    2. Thử lại để chèn hàng mới vào bảng

Có thể trong trường hợp lỗi khóa trùng lặp, công cụ lưu trữ có thể thực hiện REPLACE dưới dạng bản cập nhật thay vì xóa cộng với chèn, nhưng ngữ nghĩa là như nhau. Không có hiệu ứng nhìn thấy người dùng nào ngoài sự khác biệt có thể có trong cách các biến trạng thái của công cụ lưu trữ

mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.05 sec)

mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 1 row affected (0.06 sec)

mysql> SELECT * FROM test2;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | Old  | 2014-08-20 18:47:00 |
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
2 rows in set (0.00 sec)
3.

Bởi vì kết quả của các câu lệnh

mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.05 sec)

mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 1 row affected (0.06 sec)

mysql> SELECT * FROM test2;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | Old  | 2014-08-20 18:47:00 |
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
2 rows in set (0.00 sec)
4 phụ thuộc vào thứ tự các hàng từ
mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.05 sec)

mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 1 row affected (0.06 sec)

mysql> SELECT * FROM test2;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | Old  | 2014-08-20 18:47:00 |
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
2 rows in set (0.00 sec)
5 và thứ tự này không thể luôn luôn được đảm bảo, có thể khi đăng nhập các câu lệnh này cho nguồn và bản sao để phân kỳ. Vì lý do này, các câu lệnh
mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.05 sec)

mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 1 row affected (0.06 sec)

mysql> SELECT * FROM test2;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | Old  | 2014-08-20 18:47:00 |
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
2 rows in set (0.00 sec)
4 được gắn cờ là không an toàn cho sao chép dựa trên tuyên bố. Các câu lệnh như vậy tạo ra cảnh báo trong nhật ký lỗi khi sử dụng chế độ dựa trên câu lệnh và được ghi vào nhật ký nhị phân bằng định dạng dựa trên hàng khi sử dụng chế độ
mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.05 sec)

mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 1 row affected (0.06 sec)

mysql> SELECT * FROM test2;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | Old  | 2014-08-20 18:47:00 |
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
2 rows in set (0.00 sec)
7. Xem thêm Phần & NBSP; 17.2.1.1, Ưu điểm và nhược điểm của bản sao dựa trên tuyên bố và dựa trên hàng.

MySQL 8.0.19 và sau đó hỗ trợ

mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.05 sec)

mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 1 row affected (0.06 sec)

mysql> SELECT * FROM test2;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | Old  | 2014-08-20 18:47:00 |
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
2 rows in set (0.00 sec)
8 cũng như
mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.05 sec)

mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 1 row affected (0.06 sec)

mysql> SELECT * FROM test2;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | Old  | 2014-08-20 18:47:00 |
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
2 rows in set (0.00 sec)
5 với REPLACE, giống như với INSERT. Xem Phần & NBSP; 13.2.6.1, Chèn chèn ... Chọn câu lệnh, để biết thêm thông tin và ví dụ.

Khi sửa đổi một bảng hiện có không được phân vùng để phù hợp với phân vùng, hoặc, khi sửa đổi phân vùng của bảng đã được phân vùng, bạn có thể xem xét thay đổi khóa chính của bảng (xem Phần & NBSP; 24.6.1 Keys ”). Bạn nên lưu ý rằng, nếu bạn làm điều này, kết quả của các câu lệnh REPLACE có thể bị ảnh hưởng, giống như nếu bạn sửa đổi khóa chính của bảng không phân chia. Xem xét bảng được tạo bởi câu lệnh REPLACE3 sau:

CREATE TABLE test (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);

Khi chúng tôi tạo bảng này và chạy các câu lệnh hiển thị trong máy khách MySQL, kết quả như sau:

mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)

Bây giờ chúng tôi tạo một bảng thứ hai gần giống với bảng thứ nhất, ngoại trừ khóa chính hiện bao gồm 2 cột, như được hiển thị ở đây (văn bản nhấn mạnh):

CREATE TABLE test2 (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id, ts)
);

Khi chúng tôi chạy trên REPLACE4 cùng hai câu REPLACE như chúng tôi đã làm trên bảng REPLACE6 gốc, chúng tôi có được một kết quả khác:

mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.05 sec)

mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 1 row affected (0.06 sec)

mysql> SELECT * FROM test2;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | Old  | 2014-08-20 18:47:00 |
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
2 rows in set (0.00 sec)

Điều này là do thực tế là, khi chạy trên REPLACE4, cả hai giá trị cột REPLACE8 và REPLACE9 phải khớp với các giá trị hiện tại để hàng được thay thế; Nếu không, một hàng được chèn.