2013-03-29 80 views
21

我正在寫一個登記過程的模擬航空公司訂票數據庫和我真正想要做的是這樣的:條件INSERT INTO在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]'); 

但Postgres的不支持IF語句,而不加載PL/pgSQL擴展。我想知道是否有辦法做到這一點,或者如果在這一步中需要進行一些用戶交互?

+0

爲什麼不直接加載PL/pgSQL擴展呢? –

+0

@MattBall:在實驗室計算機上安裝postgres。使用該擴展名不在規範中。 –

回答

45

說具體命令可以這樣做:

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' 
); 

將插入SELECT語句的結果,如果客戶不存在select只會返回一行。

+1

我假設這裏有一個(非常小的)比賽? select子查詢運行,返回0行,在另一個線程中發生插入,然後發生LeadCustomer插入? –

+0

@Kevin將提出主鍵異常,應用程序將決定如何執行。 –

+1

我很困惑,這個問題沒有提到任何地方的主鍵。如果(姓,名)上有一個主鍵,爲什麼不先嚐試插入? –

1

隨着9.5版本的pgsql UPSERT的包括,使用INSERT ... ON CONFLICT DO UPDATE ...

下面的答案不再是相關的。幾年後Postgres 9.5發佈了一個更好的解決方案。

Postgres不具備「upsert」功能,無需添加新功能。
您需要做的是運行select查詢並查看是否有匹配的行。如果你這樣做,然後插入它。

我知道你不想要一個upsert,但它幾乎是一樣的。

+0

有一種方法可以做到這一點:http://stackoverflow.com/a/8702291/330315 –

+0

即使存在衝突(因爲嘗試插入),它仍會繼續增加自動遞增的ID – rohanagarwal

+0

「檢查結果,並有條件地插入「容易出現競爭條件:如果你有兩個線程同時進行,你可以得到兩個插入。 –