2016-04-01 22 views
43

Khi bạn đang upserting một hàng (PostgreSQL> = 9.5), và bạn muốn INSERT có thể chính xác giống như UPDATE có thể, bạn có thể viết nó như thế này :INSRESQL INSERT ON UPDATE CONFLICT (upsert) sử dụng tất cả các giá trị bị loại trừ

INSERT INTO tablename (id, username, password, level, email) 
       VALUES (1, 'John', 'qwerty', 5, '[email protected]') 
ON CONFLICT (id) DO UPDATE SET 
    id=EXCLUDED.id, username=EXCLUDED.username, 
    password=EXCLUDED.password, level=EXCLUDED.level,email=EXCLUDED.email 

Có cách nào ngắn hơn không? Để chỉ nói: sử dụng tất cả các giá trị EXCLUDE.

Trong SQLite tôi sử dụng để làm:

INSERT OR REPLACE INTO tablename (id, user, password, level, email) 
         VALUES (1, 'John', 'qwerty', 5, '[email protected]') 
+5

Không phải là một câu trả lời thật nhưng bạn có thể sử dụng một chút thời gian ngắn ký hiệu: 'INSERT INTO tablename (id, tên người dùng, mật khẩu, mức độ, email) VALUES (1, 'John', 'qwerty', 5 , '[email protected]') TRÊN CONFLICT (id) CẬP NHẬT THIẾT LẬP (tên người dùng, mật khẩu, cấp độ, email) = (EXCLUDED.username, EXCLUDED.password, EXCLUDED.level, EXCLUDED.email) .' Hầu như tương tự, nhưng dễ sao chép/dán/quản lý danh sách cột – foal

+0

Một tùy chọn khác là sử dụng các cột jsonb và theo cách đó bạn không phải lo lắng về các cột –

Trả lời

53

Postgres đã không được thực hiện tương đương với INSERT OR REPLACE. Từ (tôi nhấn mạnh) ON CONFLICT docs:

Nó có thể là không làm gì cả, hoặc một DO CẬP NHẬT khoản quy định cụ thể các chi tiết chính xác của hành động UPDATE để được thực hiện trong trường hợp có xung đột.

Mặc dù nó không cung cấp cho bạn viết tắt để thay thế, ON CONFLICT DO UPDATE áp dụng chung hơn vì nó cho phép bạn đặt giá trị mới dựa trên dữ liệu có từ trước. Ví dụ:

INSERT INTO users (id, level) 
VALUES (1, 0) 
ON CONFLICT (id) DO UPDATE 
SET level = users.level + 1; 
Các vấn đề liên quan