2

我有一个代码,如果它不存在,则在数据库中创建具有指定 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;
4

2 回答 2

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;
于 2013-06-23T16:16:49.143 回答
1

MySQL 有一个REPLACE语句可以完全满足您的要求:

REPLACE工作方式与 完全相同,只是如果表中的旧行与 a或索引INSERT的新行具有相同的值,则在插入新行之前删除旧行。PRIMARY KEYUNIQUE

不删除的替代方法是INSERT ... ON DUPLICATE KEY UPDATE语句

如果您指定ON DUPLICATE KEY UPDATE, 并且插入的行会导致UNIQUE索引中的重复值或PRIMARY KEY,MySQL 将执行UPDATE旧行的一个。

于 2013-06-23T16:10:12.890 回答