2009-12-15 68 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

相关问题