2011-05-11 96 views
2

在写我的问题(HOWTO:插入一个新的条目,如果它已经存在,更新它),我发现在Related Questions一些答案:DBD :: SQLite的:插入或更新 - 问题

$sql = "INSERT OR REPLACE INTO $table (Id, Name, Rating) VALUES(?, ?, ?)"; 
$sth_rating = $dbh->prepare($sql); 
$sth_rating->execute($id, $name, $rating); 

$sql = "INSERT OR IGNORE INTO $table (Id, Name, Rating) VALUES (?, ?, ?)"; 
$sth_rating = $dbh->prepare($sql); 
$sth_rating->execute($id, $name, $rating); 

$sql = "UPDATE $table SET Rating = ? WHERE Id = ?"; 
$sth_rating = $dbh->prepare($sql); 
$sth_rating->execute($rating, $id); 

第二种方法比第一种方法更安全吗?

+0

你想要完全替换现有场或者如果它存在,只需要更新其评级? http://en.wikipedia.org/wiki/Upsert – Schwern 2011-05-11 07:19:41

+0

除“评级”之外的所有字段都来自另一个表,并且始终是相同的(对于该ID)。 通常情况下,条目将被添加,但如果它们已经存在,则应调整可能的新“评估”值。 – 2011-05-11 07:56:26

回答

4

第二种方法是较少安全,因为它是非原子的。换句话说,它发生在多个步骤中。考虑两个更新相同数据的过程。时间在减少。

Process 1      Process 2 

INSERT OR IGNORE... 
           INSERT OR IGNORE... 
           UPDATE... 
UPDATE... 

进程1首先启动,但进程2潜入并在其之间进行更新。然后,流程1正在进行流程2的更新。

这种情况在这种情况下并不是很糟糕,无论是哪种情况,两个过程都会相互冲突,但是通过扩展技术可以很容易地陷入麻烦。

(除非我误解了这个问题,你想要什么是upsert