我想ON DUPLICATE KEY UPDATE在 Zend Framework 1.5 中使用,这可能吗?
例子
INSERT INTO sometable (...)
VALUES (...)
ON DUPLICATE KEY UPDATE ...
我想ON DUPLICATE KEY UPDATE在 Zend Framework 1.5 中使用,这可能吗?
例子
INSERT INTO sometable (...)
VALUES (...)
ON DUPLICATE KEY UPDATE ...
我为 Zend 工作,并且专门为 Zend_Db 工作了很多。
ON DUPLICATE KEY UPDATE不,该语法不支持 API 。对于这种情况,您必须query()自己简单地使用并形成完整的 SQL 语句。
我不建议将值插入到 SQL 中,如 harvejs 所示。使用查询参数。
编辑:您可以避免使用VALUES()表达式重复参数。
$sql = "INSERT INTO sometable (id, col2, col3) VALUES (:id, :col2, :col3)
ON DUPLICATE KEY UPDATE col2 = VALUES(col2), col3 = VALUES(col3)";
$values = array("id"=>1, "col2"=>327, "col3"=>"active");
作为侧边栏,您可以通过以下方式简化ON DUPLICATE KEY UPDATE子句并减少脚本需要执行的处理量VALUES():
$sql = 'INSERT INTO ... ON DUPLICATE KEY UPDATE id = VALUES(id), col2 = VALUES(col2), col3 = VALUES(col3)';
有关更多信息,请参阅http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html。
@Bill Karwin:很好的解决方案!但是如果使用命名占位符(“:id”,“:col1”,...)而不是问题符号会更好。比您不需要通过 array_marge 复制值。此外,如果使用“INSERT”而不是“VALUES”的“SET”语法,代码会更简单地为任何字段集自动生成。
$sql = 'INSERT INTO sometable SET id = :id, col2 = :col2, col3 = :col3
ON DUPLICATE KEY UPDATE id = :id, col2 = :col2, col3 = :col3';
$arrayData = array('column1' => value1, 'column2' => value2, ...)
class Model_Db_Abstract extends Zend_Db_Table_Abstract
{
protected $_name;
protected $_primaryKey;
public function insertOrUpdate($arrayData)
{
$query = 'INSERT INTO `'. $this->_name.'` ('.implode(',',array_keys($arrayData)).') VALUES ('.implode(',',array_fill(1, count($arrayData), '?')).') ON DUPLICATE KEY UPDATE '.implode(' = ?,',array_keys($arrayData)).' = ?';
return $this->getAdapter()->query($query,array_merge(array_values($arrayData),array_values($arrayData)));
}
}
用法:
例如。Model_Db_Contractors.php
class Model_Db_Contractors extends Model_Db_Abstract
{
protected $_name = 'contractors';
protected $_primaryKey = 'contractor_id';
...
}
索引控制器.php
class IndexController extends Zend_Controller_Action
{
public function saveAction()
{
$contractorModel = new Model_Db_Contractors();
$aPost = $this->getRequest()->getPost();
/* some filtering, checking, etc */
$contractorModel->insertOrUpdate($aPost);
}
}
改用这个:
REPLACE INTO sometable SET field ='value'.....
如果存在则更新,如果不存在则插入。这是标准 mysql api 的一部分。
更新 Pawel's Answer 以支持单独插入和更新数据,并且还支持 Zend Db 表达式
class Model_Db_Abstract extends Zend_Db_Table_Abstract
{
protected $_name;
protected $_primaryKey;
public function insertOrUpdate($arrayData)
{
$insertDataValuesForQuery = [];
$queryParams = [];
foreach ($insertData as $key => $value) {
if (gettype($value) == "object") {
array_push($insertDataValuesForQuery, $value->__toString());
continue;
}
array_push($insertDataValuesForQuery, "?");
array_push($queryParams, $value);
}
$updateDataValuesForQuery = [];
foreach ($updateData as $key => $value) {
if (gettype($value) == "object") {
array_push($updateDataValuesForQuery, $key . " = " . $value->__toString());
continue;
}
array_push($updateDataValuesForQuery, $key . " = ?");
array_push($queryParams, $value);
}
$query = 'INSERT INTO ' . $this->_name . ' (' . implode(',', array_keys($insertData)) . ') VALUES (' . implode(',', $insertDataValuesForQuery) . ') ON DUPLICATE KEY UPDATE ' . implode(' , ', $updateDataValuesForQuery);
return $this->getAdapter()->query($query, $queryParams);
}
}
你可以简单地做这样的事情:
在您的 id 上设置唯一索引
进而
try {
do insert here
} catch (Exception $e) {
do update here
}