PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Trả lại các hàng từ INSERT với ON CONFLICT mà không cần cập nhật

Đây là sự cố lặp lại của SELECT or INSERT , liên quan đến (nhưng khác với) một UPSERT. Chức năng UPSERT mới trong Postgres 9.5 vẫn là một công cụ.

WITH ins AS (
   INSERT INTO names(name)
   VALUES ('bob')
   ON     CONFLICT ON CONSTRAINT names_name_key DO UPDATE
   SET    name = NULL
   WHERE  FALSE      -- never executed, but locks the row
   RETURNING id
   )
SELECT id FROM ins
UNION  ALL
SELECT id FROM names
WHERE  name = 'bob'  -- only executed if no INSERT
LIMIT  1;

Bằng cách này, bạn không thực sự viết một phiên bản hàng mới mà không cần.

Tuy nhiên , vẫn còn một trường hợp góc nhỏ cho điều kiện cuộc đua . Các giao dịch đồng thời có thể đã thêm một hàng xung đột, hàng này chưa được hiển thị trong cùng một câu lệnh. Sau đó, INSERT SELECT trống rỗng.

Giải pháp thích hợp cho UPSERT một hàng:

  • CHỌN hoặc CHÈN trong một hàm có nguy cơ gặp phải các điều kiện về chủng tộc không?

Các giải pháp chung cho UPSERT số lượng lớn:

  • Cách sử dụng RETURNING với ON CONFLICT trong PostgreSQL?

Không có tải ghi đồng thời

Nếu không thể ghi đồng thời (từ một phiên khác), bạn không cần khóa hàng và có thể đơn giản hóa:

WITH ins AS (
   INSERT INTO names(name)
   VALUES ('bob')
   ON     CONFLICT ON CONSTRAINT names_name_key DO NOTHING  -- no lock needed
   RETURNING id
   )
SELECT id FROM ins
UNION  ALL
SELECT id FROM names
WHERE  name = 'bob'  -- only executed if no INSERT
LIMIT  1;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hiểu hiệu suất truy vấn PostgreSQL

  2. Có gì mới trong PgBouncer 1.6

  3. Postgres nhúng cho các bài kiểm tra khởi động mùa xuân

  4. tệp đầu vào dường như là một kết xuất định dạng văn bản. Vui lòng sử dụng psql

  5. Phát hiện xem một giá trị có chứa ít nhất một chữ số trong PostgreSQL hay không