代码之家  ›  专栏  ›  技术社区  ›  meder omuraliev

SQL:只在表中插入新行/记录吗?

  •  6
  • meder omuraliev  · 技术社区  · 16 年前

    我经常解析json提要,只需要插入提要中的最新用户,而忽略现有用户。

    ON DUPLICATE KEY UPDATE INSERT IGNORE

    users
    1     John
    2     Bob
    

    部分JSON:

    { userid:1, name:'John' },
    { userid:2, name:'Bob' },
    { userid:3, name:'Jeff' }
    

    从这个提要中,我只想插入杰夫。我可以对所有用户进行简单的循环,并执行简单的SELECT查询,查看用户id是否已经在表中,如果没有,我可以执行INSERT,但我怀疑这不是一种高效实用的方法。

    5 回复  |  直到 15 年前
        1
  •  5
  •   Henrik Opel    16 年前

    ON DUPLICATE KEY UPDATE alternative允许您将更新与插入的决定提交给数据库:

    INSERT INTO table (userid, name) VALUES (2, 'Bobby');
      ON DUPLICATE KEY UPDATE name = 'Bobby';
    

    如果用户ID为2的条目已经存在,则将名称字段更新为“Bobby”。

    您可以将其用作 INSERT IGNORE

    INSERT INTO table (userid, name) VALUES (2, 'Bobby');
      ON DUPLICATE KEY UPDATE name = name;
    

    插入忽略 .


    另一种选择是 REPLACE :

    REPLACE INTO table (userid, name) VALUES (2, 'Bobby');
    


    请注意,这两个版本都是SQL的MySQL特定扩展。

        2
  •  4
  •   Dani García    14 年前

    对于Zend Framework,我所做的是尝试/捕获插入语句,并根据异常代码采取进一步行动:

    class Application_Model_DbTable_MyModel extends Zend_Db_Table_Abstract
    
        public function insert($aData, $bIgnore = false) 
        {
    
            try 
            {
                $id =  parent::insert($aData);
            } 
            catch(Zend_Db_Statement_Mysqli_Exception $e) 
            {
                // code 1062: Mysqli statement execute error : Duplicate entry
                if($bIgnore && $e->getCode() == 1062) 
                {
                    // continue;
                } 
                else 
                {
                    throw $e;
                }
            }
            return !empty($id) ? $id : false;
        }
    }
    
        3
  •  2
  •   Alix Axel    16 年前

    INSERT IGNORE INTO table (userid, name) VALUES (2, 'Bob');
    

    如果用户ID 2已经存在,它将忽略并继续进行下一次插入。

    另一种选择可能是使用REPLACE INTO语法。

    REPLACE INTO table (userid, name) VALUES (2, 'Bob');
    

    这将尝试插入,如果记录已经存在,它将在再次插入之前将其删除。

        4
  •  1
  •   Sébastien    13 年前

    我的解决方案:

    /**
     * Perform an insert with the IGNORE word
     *
     * @param $data array
     * @return number the number of rows affected
     */
    public function insertIgnore(array $data)
    {
        // Start of query
        $sql = sprintf("INSERT IGNORE INTO %s (", $this->getAdapter()->quoteIdentifier($this->info('name')));
        // Retrieve column identifiers
        $identifiers = array_keys($data);
        foreach ($identifiers as $key => $value) {
            // Quote identifier
            $identifiers[$key] = $this->getAdapter()->quoteIdentifier($value);
        }
        // Concat column identifiers
        $sql .= implode(', ', $identifiers);
        $sql .= ") VALUES (";
        foreach ($data as $key => $value) {
            // Quote values
            $data[$key] = $this->getAdapter()->quote($value);
        }
        // Concat values identifiers
        $sql .= implode(', ', $data);
        $sql .= ")";
        // Process the query
        return $this->getAdapter()->query($sql)->rowCount();
    }
    
        5
  •  0
  •   o.k.w    16 年前

    在循环中,您可以先进行更新,如果没有受影响的行,则意味着这是一个新条目。跟踪这些“失败的更新”,然后将其作为新条目插入。