CodeIgniterでアクティブレコードクエリを実行して、既存のレコードが既に存在する場合は更新するか、存在しない場合は挿入することができますか?
既存のレコードを見つけるために最初にクエリを実行することでこれを実行できることを理解していますが、最も効率的なアプローチを探しています。
基本的にあなたが探しているのはこれかもしれません_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);
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が存在する場合は更新クエリを実行し、そうでない場合は挿入クエリを実行します。
運のベスト
私はこのアプローチを使用しています:
更新する_unique id
_のテーブルmytable
を_column xyz
_およびunique
キーで構成します
重複を避けるために_$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
_の値が存在しない場合、これは行を挿入します
行が挿入された場合はinsert_id()
を使用してid
を返し、行が挿入されなかった場合は更新します。
_if(!$this->db->insert_id()){
$query=$this->db ->where('xyz', $data['xyz'])
->update('my_table',$data);
};
_
ミラザの回答を更新-簡単に完了
$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);
これは同じことを達成できる方法です
/**
* 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);
}