2009-12-15 72 views
3

我有一個php腳本可以將新部件插入到postgres數據庫中。我想在創建零件之前檢查零件是否存在。我怎樣才能做到這一點。我正在使用通常的INSERT INTO子句。插入前檢查是否存在記錄

回答

6

SELECT首先,要知道,如果你一定要INSERTUPDATE,如:

if (
    $db->fetchOne(
     'SELECT COUNT(1) FROM parts WHERE article_number = ?', 
     $p->article_number 
    ) 
) { 
    $db->update(
     'parts', 
     $p->to_array(), 
     $db->quoteInto('article_number = ?', $p->article_number) 
    ); 
} 
else { 
    $db->insert('parts', $p->to_array()); 
} 

重新米倫的評論:大一點!使用默認的PostgreSQL事務隔離級別(READ COMMITTED),另一個進程可能會在您的SELECT之後但在您的INSERT之前插入(並提交)「您的」部分。

對於我們構建的應用程序,我們通常只捕獲數據庫異常,並對其進行處理(通知用戶重試)。或者你可以用SET TRANSACTION ISOLATION LEVEL SERIALIZABLE去。見Transaction Isolation

+0

好的,做一個SELECT else子句。我是這個新手,你可以幫我看看代碼嗎?我可以做SELECT而不是其他位。非常感謝你的偉大思想。 – 2009-12-15 20:11:38

+0

我已經添加了代碼Russel。 $ db是Zend_Db_Adapter http://framework.zend.com/manual/en/zend.db.html#zend.db.adapter – 2009-12-15 20:17:20

+0

當檢查存在之前和之前插入具有相同article_number的記錄時會發生什麼插入(又名比賽條件)? – 2009-12-15 21:38:32

1

如果您很少會遇到衝突:採取樂觀的方法,只需插入新的方法,並在發生時處理唯一性違規。當它失敗時,這會使當前事務失效,所以如果你在其中做了很多工作,首先檢查是值得的。在這種情況下,我更喜歡SELECT EXISTS(SELECT 1 ... FROM ... WHERE ...)

無論如何,你必須處理違反唯一性的可能性。即使您先檢查,也有可能併發事務插入相同的記錄並首先提交。

5
insert into parts(article_number,category) 
select 'KEYB','COMPTR' 
where not exists(select * from parts where article_number = 'KEYB') 
+0

偉大的解決方案,如果我們想默默地忽略重複。不受競賽狀況的影響。我自己使用它。 – filiprem 2009-12-16 22:46:53

相關問題