CodeIgniter - активная запись, если новая или обновленная в дубликате

Возможно ли выполнить запрос активной записи в CodeIgniter, который обновит существующую запись, если она уже существует или вставляется, если она не указана для данного ключа?

Я понимаю, что это можно сделать, сначала запросив, чтобы найти существующую запись, но я ищу наиболее эффективный подход.

Ответы

Ответ 1

В основном то, что вы ищете, может быть INSERT ... ON DUPLICATE KEY UPDATE - при условии, что вы используете MySQL, а ваш идентификатор - это уникальный ключ на столе.

Вам придется вручную построить запрос и перейти к функции $this->db->query() вместо любой встроенной активной записи, например, вспомогательные функции драйвера DB.

Пример:

$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
                                      ));

Ответ 2

Если вы используете Codeigniter 3.0 или выше, вам может потребоваться использовать "$ this- > db- > replace()". Согласно руководству пользователя:

"Этот метод выполняет оператор REPLACE, который в основном является стандартом SQL для (необязательного) DELETE + INSERT с использованием ключей PRIMARY и UNIQUE в качестве определяющего фактора. В нашем случае это избавит вас от необходимости внедрять сложные логики с различными комбинациями вызовов select(), update(), delete() и insert().

Другими словами,

  • Если он не существует, он вставляет новую запись.
  • Если он существует, он обновляет его в соответствии с его основным или уникальным ключом.

Просто используйте его прямо из коробки, например:

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

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

Батареи не требуются!!!

Ответ 3

Я не знаю, что класс Active Record Class Codeigniter имеет этот метод или не проверяет 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

ПРИМЕЧАНИЕ. Вы должны выбрать первичный ключ из результатов и поместить его в исходное состояние.

Это очень важно, так что я делаю, когда получаю данные с контроллера. Я просто проверяю, что у него есть ID или нет, если присутствует Id, тогда я произвел запрос на обновление, если не тогда, когда я уволил запрос на ввод.

ЛУЧШАЯ УДАЧЬ

Ответ 4

Вы можете сделать это проще:

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

Ответ 5

Я использую этот подход:

  • настройте таблицу mytable клавишей unique id и unique для column xyz, которую вы хотите обновить

  • попробуйте вставить массив $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);
    };  
    

Ответ 6

Вот такой метод, который, я надеюсь, может выполнить тот же

   /**
    * 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);
}