【问题标题】:Use" INSERT ... ON DUPLICATE KEY UPDATE" to insert multiple records使用“INSERT ... ON DUPLICATE KEY UPDATE”插入多条记录
【发布时间】:2014-06-05 05:03:33
【问题描述】:

我的表格结构

表格:标记

我的目标: 我想用条件插入或更新多条记录

我目前正在通过此查询进行检查

第一步

SELECT * FROM `marks` WHERE `student` =115 AND `param` =1

第二步

if 
    records found by matching above criteria i just update record by my new values 
else
    insert new record into my table 

它会正常工作的。但我想减少代码并将其优化为单个查询。它可能与否? 我在 MySQL 文档 INSERT ... ON DUPLICATE KEY UPDATE 上找到了这个。如果这是一个解决方案。如何通过查询实现?

注意:我使用的是 Yii 框架。也欢迎 Yii 的建议

已编辑: 此查询不会更新 rows 。但从插入正常工作中逃脱

INSERT INTO marks(`student`,`param,mark`,`created`,`lastmodified`,`status`) 
VALUES 
(11,30,10,'00-00-00 00:00:00','00-00-00 00:00:00','U')
ON DUPLICATE KEY UPDATE `mark`=VALUES(`mark`)

【问题讨论】:

  • 第一步:在 (student, param) 上创建一个唯一索引,然后像你一样尝试插入,ON DUPLICATE KEY UPDATE SET mark=VALUES(mark)
  • @Wrikken 如何将两列组合设置为唯一的。因为不同的学生有相同的参数。 student 和 param 组合都是唯一的。我不熟悉索引。请需要更多信息。谢谢
  • @Wrikken 我编辑我的问题。请审查它。它不会更新现有记录。但它正确地跳过了重复的条目。我为字段 student 和 param 添加唯一索引。
  • ALTER TABLE marks ADD UNIQUE (student, param);,然后INSERT INTO marks (student, param, mark, created) VALUES (11,20,10,NOW()) ON DUPLICATE KEY UPDATE SET mark=VALUES(mark); 应该可以工作。
  • @Wrikken 这个问题解决了。谢谢你的评论。它对其他人有用

标签: php mysql yii insert-update


【解决方案1】:

查看这篇文章Yii INSERT ... ON DUPLICATE UPDATE。他们建议您不要使用此功能。但我希望它使用,所以我从 CDbCommand 扩展了我自己的组件并为 ON DUPLICATE KEY UPDATE 添加方法:

public function insertDuplicate($table, $columns, $duplicates)
{
    $params=array();
    $names=array();
    $placeholders=array();
    foreach($columns as $name=>$value)
    {
        $names[]=$this->getConnection()->quoteColumnName($name);
        if($value instanceof CDbExpression)
        {
            $placeholders[] = $value->expression;
            foreach($value->params as $n => $v)
                $params[$n] = $v;
        }
        else
        {
            $placeholders[] = ':' . $name;
            $params[':' . $name] = $value;
        }
    }

    $d = array();
    foreach($duplicates as $duplicate)
    {
        $d[] = '`' . $duplicate . '` = VALUES(`'.$duplicate.'`)';
    }
    $sql='INSERT INTO ' . $this->getConnection()->quoteTableName($table)
        . ' (' . implode(', ',$names) . ') VALUES ('
        . implode(', ', $placeholders) . ') ON DUPLICATE KEY UPDATE ' . implode(', ', $d);
    return $this->setText($sql)->execute($params);
}

使用示例:

Yii::app()->db->createCommand()->insertDuplicate('user', [
   'id' => $this->id,
   'token' => $token,
   'updated' => date("Y-m-d H:i:s"),
], ['token', 'updated']);

如果记录存在,此命令将使用此参数创建用户或更新 tokenupdated 字段。

【讨论】:

  • 你能给出这个函数的示例参数吗? $table, $columns, $duplicates 如何传递这些值
  • @RyanBabu 当然,我添加了一些示例
  • 在此之前需要任何字段索引吗?请在编辑部分查看我的问题。该查询不起作用。我在哪里做错了,我在这里无法理解我的问题。我知道你的代码很有用。我只是单独运行那个 sql。它不会更新现有值。谢谢你的例子。很好实施
  • INSERT INTO 标记(student,param,mark,created,lastmodified,status) 出现错误:param,mark 它必须由 'param'、'mark'
  • 我发现了我的问题@alex 感谢您的回答,现在我使用您的功能。我没有更新其他值。**param=values(param),student=values(student)**这里不需要。两个值相同。现在它的工作
【解决方案2】:

不要在您的编程中实现“INSERT ... ON DUPLICATE”,因为它是 MySQL 特定的。当您从 MySQL 迁移到其他数据库时,您的程序无法按照 Database Abstraction 的概念与新数据库通信

这样试试

    function actionName()
    {
        $id=$_POST['marks']['id']; //Pick the ID from your form values
        $model = Marks::model()->findByPk($id); //Check the records in the Marks table
        if (!$model) //If not found create a new Model for insertion. If records are there it will update the model
            $model = new Marks();
        $model->attributes = $_POST['marks']; //Assign the form values to attributes
        $model->save();
    }

【讨论】:

  • 你读过他的问题吗?他说他想在一个查询中做到这一点
  • 感谢您的建议。我的应用程序不需要数据库更改功能。我也在使用这种类型的过程。由于数据库命中率,我想将其更改为 sql。插入率非常高。这个过程对我来说看起来很慢。我需要优化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-26
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 2017-04-24
  • 2013-10-03
  • 2015-07-30
相关资源
最近更新 更多