我有一个代码,如果它不存在,则在数据库中创建一个具有指定id的行,否则更新该行。它有点慢(它检查是否存在行然后插入/更新它)并且我想要优化它。如何将整个事物合并到一个SQL查询中?我想我应该使用INSERT ... ON DUPLICATE KEY UPDATE但我不明白它是如何工作的。谢谢。
$objectExists = true;
try {
$object = new Object();
$object->loadFromDatabaseById($this->id, $dbh); // tries to load object from database, throws
// ExceptionNotFound if object with specified id does not exist
}
catch(ExceptionNotFound $e) {
$objectExists = false;
}
if($objectExists)
$sth = $dbh->prepare(
'UPDATE objects ' .
'SET property1 = :property1, ' .
'property2 = :property2, ' .
'property3 = :property3 ' .
'WHERE id = :id'
);
else
$sth = $dbh->prepare(
'INSERT INTO objects ' .
'SET id = :id, ' .
'property1 = :property1, ' .
'property2 = :property2, ' .
'property3 = :property3'
);
$sth->bindParam(':id', $this->id, \PDO::PARAM_INT);
$sth->bindParam(':property1', $this->property1, \PDO::PARAM_STR);
$sth->bindParam(':property2', $this->property2, \PDO::PARAM_STR);
$sth->bindParam(':property3', $this->property3, \PDO::PARAM_INT);
$sth->execute();
$this->id = (int)$this->id;
答案 0 :(得分:1)
MySQL has a REPLACE
statement完全符合您的要求:
REPLACE
与INSERT
完全相同,只是如果表中的旧行与PRIMARY KEY
或UNIQUE
索引的新行具有相同的值,在插入新行之前删除旧行。
没有删除的替代方案是INSERT ... ON DUPLICATE KEY UPDATE
statement:
如果指定
ON DUPLICATE KEY UPDATE
,并且插入的行会导致UNIQUE
索引或PRIMARY KEY
中的重复值,则MySQL会执行旧行的UPDATE
答案 1 :(得分:1)
只要id
是主键或唯一键/索引,您就可以将其缩短为 -
$sth = $dbh->prepare(
'INSERT INTO objects ( id, property1, property2, property3) ' .
'VALUES ( :id,:property1,:property2,:property3) '.
'ON DUPLICATE KEY UPDATE ' .
'property1 = :property1, ' .
'property2 = :property2, ' .
'property3 = :property3 '
);
$sth->bindParam(':id', $this->id, \PDO::PARAM_INT);
$sth->bindParam(':property1', $this->property1, \PDO::PARAM_STR);
$sth->bindParam(':property2', $this->property2, \PDO::PARAM_STR);
$sth->bindParam(':property3', $this->property3, \PDO::PARAM_INT);
$sth->execute();
$this->id = (int)$this->id;