通常,在更新/插入时使用on duplicate key update
语句。但我正在插入/更新这样的表:
id | neutral text | language | translation
---+--------------+----------+------------
0 | SUBMIT | en | Submit
1 | SUBMIT | cs | Odeslat
2 | SUBMIT | fr | Démarrer
我知道我应该做3张表,但这个项目没有那么大,所以我决定把它做得相当简单。
所以现在,当我想更改或添加翻译时,可以这样做:
/*
$this->lang_class->table = the name of my table
$offset = neutral text name
$this->lang = language name
$value = new translation
*/
$this->debug("Translate attempt!<br />");
//Try to update, insert will be performed if update returns 0 rows
$update = $this->pdo->prepare("UPDATE `{$this->lang_class->table}` SET content='$value' WHERE lang='{$this->lang}' AND name='$offset'");
$update->execute(); //try to update
if($update->rowCount()==0) { //If no update happened, insert
$this->debug("Creating new translation entry.<br />");
$this->execsql("INSERT INTO `{$this->lang_class->table}` (lang, name, content) VALUES ('{$this->lang}', '$offset', '$value')");
}
return $value;
问题是,有时可能会出现新译本与旧译本相匹配的情况。在这种情况下,UPDATE将返回0行,并执行INSERT
那么,如果我只想坚持一张桌子,我应该使用什么方法呢?
正确的选项是在表上创建一个唯一的复合索引(name,lang),并使用ON DUPLICATE KEY UPDATE
追加新值。这正是ON DUPLICATE KEY UPDATE
在MySQL中存在的原因。
当您运行两个查询时,您可以更改第一个:
SELECT count(*) FROM translate_table WHERE lang='$lang' AND name='$name';
然后,如果此查询返回0,则可以使用您的insert:
$this->execsql("INSERT INTO `{$this->lang_class->table}` (lang, name, content) VALUES ('{$this->lang}', '$offset', '$value')");
否则运行您的更新查询:
$this->pdo->prepare("UPDATE `{$this->lang_class->table}` SET content='$value' WHERE lang='{$this->lang}' AND name='$offset'")->execute();
您可以在neutral_text
和language
字段上使用密钥集。特别是,无论如何都应该创建该密钥,并且它应该是唯一的。