2013-03-29 36 views
21

Tôi đang viết một thủ tục đặt phòng cho một cơ sở dữ liệu đặt vé giả và những gì tôi thực sự muốn làm là một cái gì đó như thế này:INSERT Conditional VÀO tuyên bố trong postgres

IF EXISTS (SELECT * FROM LeadCustomer 
    WHERE FirstName = 'John' AND Surname = 'Smith') 
THEN 
    INSERT INTO LeadCustomer (Firstname, Surname, BillingAddress, email) 
    VALUES ('John', 'Smith', '6 Brewery close, 
      Buxton, Norfolk', [email protected]'); 

Nhưng Postgres không hỗ trợ IF báo cáo mà không tải phần mở rộng PL/pgSQL. Tôi đã tự hỏi nếu có một cách để làm một số tương đương với điều này hoặc nếu có chỉ cần có được một số tương tác người dùng trong bước này?

+0

Tại sao không chỉ nạp phần mở rộng PL/pgSQL? –

+0

@MattBall: Làm việc với cài đặt postgres trên các máy tính trong phòng thí nghiệm. Sử dụng phần mở rộng đó không có trong spec. –

Trả lời

45

Đó lệnh cụ thể có thể được thực hiện như thế này:

insert into LeadCustomer (Firstname, Surname, BillingAddress, email) 
select 
    'John', 'Smith', 
    '6 Brewery close, Buxton, Norfolk', '[email protected]' 
where not exists (
    select * from leadcustomer where firstname = 'John' and surname = 'Smith' 
); 

Nó sẽ chèn kết quả của câu lệnh select, và select sẽ chỉ trả lại một hàng nếu khách hàng không tồn tại.

+1

Tôi cho rằng có một cuộc đua (rất nhỏ) ở đây? Truy vấn con được chọn chạy, trả về 0 hàng, một chèn xảy ra trong một chuỗi khác, và sau đó chèn LeadCustomer xảy ra? –

+0

@Kevin Một ngoại lệ chính sẽ được nâng lên và ứng dụng sẽ quyết định phải làm gì. –

+1

Tôi đang bối rối, câu hỏi không đề cập đến các khóa chính ở bất kỳ đâu. Nếu có một khóa chính trên (firstname, họ) tại sao bạn sẽ không chỉ cần thử chèn đầu tiên? –

1

Tính đến 9,5 phiên bản của pgsql upsert được bao gồm, sử dụng INSERT ... ON CONFLICT DO UPDATE ...

Câu trả lời dưới đây là không còn phù hợp. Postgres 9.5 đã được phát hành một vài năm sau đó với một giải pháp tốt hơn.

Postgres không có chức năng "upsert" mà không thêm chức năng mới.
Điều bạn sẽ phải làm là chạy truy vấn chọn và xem liệu bạn có các hàng phù hợp hay không. Nếu bạn làm, sau đó chèn nó.

Tôi biết bạn không muốn có chính xác hơn, nhưng cũng khá giống nhau.

+0

Có một cách để làm điều đó: http://stackoverflow.com/a/8702291/330315 –

+0

điều này sẽ tiếp tục tăng id tự động tăng lên ngay cả khi có xung đột (khi chèn được thử) – rohanagarwal

+0

"Kiểm tra kết quả, và có điều kiện chèn "là dễ bị điều kiện chủng tộc: Nếu bạn có hai chủ đề làm điều đó cùng một lúc, bạn có thể nhận được hai chèn. –