web-dev-qa-db-ja.com

CodeIgniter-新規の場合、または複製時に更新する場合のアクティブなレコードの挿入

CodeIgniterでアクティブレコードクエリを実行して、既存のレコードが既に存在する場合は更新するか、存在しない場合は挿入することができますか?

既存のレコードを見つけるために最初にクエリを実行することでこれを実行できることを理解していますが、最も効率的なアプローチを探しています。

24
user4718286

基本的にあなたが探しているのはこれかもしれません_INSERT ... ON DUPLICATE KEY UPDATE_-MySQLを使用していて、IDがテーブル上の一意のキーである場合。

クエリを手動で構築し、DBドライバーのヘルパー関数のような組み込みアクティブレコードの代わりに$this->db->query()関数に渡す必要があります。

例:

_$sql = 'INSERT INTO menu_sub (id, name, desc, misc)
        VALUES (?, ?, ?, ?)
        ON DUPLICATE KEY UPDATE 
            name=VALUES(name), 
            desc=VALUES(desc), 
            misc=VALUES(misc)';

$query = $this->db->query($sql, array( $id, 
                                       $this->validation->name, 
                                       $this->validation->desc, 
                                       $this->validation->misc
                                      ));
_

Codeigniter 3.0以降を使用している場合は、「$ this-> db-> replace()」の使用を検討してください。ユーザーガイドによると:

「このメソッドは、基本的に(オプション)DELETE + INSERTのSQL標準であるREPLACEステートメントを実行し、PRIMARYキーとUNIQUEキーを決定要因として使用します。この場合、異なる組み合わせで複雑なロジックを実装する必要がなくなります。 select()、update()、delete()、およびinsert()の呼び出し。」

言い換えると、

  • 存在しない場合は、新しいレコードを挿入します。
  • 存在する場合は、主キーまたは一意のキーに従って更新します。

箱から出してそのまま使用するだけです:

$data = array(
        'title' => 'My title',
        'name'  => 'My Name',
        'date'  => 'My date'
);

$this->db->replace('table', $data);

バッテリーは必要ありません!!!

もっと簡単にできます:

$sql = $this->db->insert_string(table, $array) . ' ON DUPLICATE KEY UPDATE ' .
implode(', ', $array);
$this->db->query($sql);
3
Milaza

Codeigniter Active Recordクラスにこのメソッドがあるかどうか、または codeigniter docs がアクティブレコードクラスに含まれるメソッドをチェックしていないことを知りません。

ただし、codigniterのコアモデルを拡張するこのスルーを実現できます。この方法を使用すると、このモデルクラスを拡張するすべてのモデルに対してこのメ​​ソッドを使用できます。 MY_model.phpをapplication/core /に追加し、次のコードを記述します。

Class MY_Model extends CI_Model
{
  public function insert_update($data)
  {
       // code for checking existing record.
       if(//existing record)
           fire the update query
       else
           fire the insert query

       return insert/update id;

  }
}

上記のファイルを作成した後、すべてのモデルの親クラスを新しい拡張モデル、つまりMY_Modelに変更する必要があります

class some_model extends MY_Model

[〜#〜] note [〜#〜]:結果から主キーを選択し、where条件に入れる必要があります。

それは非常に重要なので、コントローラーからデータを取得するときに、IDがあるかどうかを確認するだけで、IDが存在する場合は更新クエリを実行し、そうでない場合は挿入クエリを実行します。

運のベスト

3
siddhesh

私はこのアプローチを使用しています:

  1. 更新する_unique id_のテーブルmytableを_column xyz_およびuniqueキーで構成します

  2. 重複を避けるために_$data_を使用して、配列_INSERT IGNORE INTO_を挿入しようとします

    _$insert_query = $this->db->insert_string('bt_ical_list', $data);
    $insert_query = str_replace('INSERT INTO','INSERT IGNORE INTO',$insert_query);
    $this->db->query($insert_query); 
    _

    _column xyz_の値が存在しない場合、これは行を挿入します

  3. 行が挿入された場合はinsert_id()を使用してidを返し、行が挿入されなかった場合は更新します。

    _if(!$this->db->insert_id()){
        $query=$this->db    ->where('xyz', $data['xyz'])
                            ->update('my_table',$data);
    };  
    _
1
Vickel

ミラザの回答を更新-簡単に完了

    $updt_str = '';
    foreach ($array as $k => $v) {
        $updt_str = $updt_str.' '.$k.' = '.$v.',';
    }
    $updt_str = substr_replace($updt_str,";", -1);
    $this->db->query($this->db->insert_string('table_name', $array).' ON DUPLICATE KEY UPDATE '.$updt_str);
0
WC2

これは同じことを達成できる方法です

   /**
    * Used to insert new row if a duplicate entry is encounter it performs an update
    * @param string $table table name as string
    * @param array $data associative array of data and columns
    * @return mixed 
    */
   private function updateOnExist($table, $data)
   {
        $columns    = array();
        $values     = array();
        $upd_values = array();
        foreach ($data as $key => $val) {
            $columns[]    = $this->db->escape_identifiers($key);
            $val = $this->db->escape($val);
            $values[]     = $val;
            $upd_values[] = $key.'='.$val;
        }
        $sql = "INSERT INTO ". $this->db->dbprefix($table) ."(".implode(",", $columns).")values(".implode(', ', $values).")ON DUPLICATE KEY UPDATE".implode(",", $upd_values);
        return $this->db->query($sql);
}
0
jdialogc