2010-07-29 35 views
16

Tôi có một Mô hình CodeIgniter/PHP và tôi muốn chèn một số dữ liệu vào cơ sở dữ liệu.Làm cách nào để sử dụng ON CẬP NHẬT KEY DUPLICATE trong mô hình CodeIgniter của tôi?

Tuy nhiên, tôi đã thiết lập này trong truy vấn SQL 'thô' của tôi:

ON DUPLICATE KEY UPDATE duplicate=duplicate+1 

Tôi đang sử dụng CodeIgniter và đang chuyển đổi tất cả trước các truy vấn trong điều khiển SQL của tôi để ActiveRecord. Có cách nào để làm điều này từ bên trong mô hình dựa trên ActiveRecord không?

Cảm ơn!

Jack

Trả lời

2

Liên kết đến chuỗi diễn đàn ở trên bị hỏng. Tôi không biết cách nào tốt hơn là chỉ sử dụng truy vấn db-> cho cuộc gọi, nếu ai đó có giải pháp tốt hơn, hãy đăng bài đó.

$result = $this->CI->db->query(
    "INSERT INTO tablename (id, name, duplicate) VALUES (1, 'Joe', 1) ". 
    "ON DUPLICATE KEY UPDATE duplicate=duplicate+1"); 

Tôi hy vọng điều này sẽ giúp ai đó tìm kiếm giải pháp cho việc này.

4

Bạn có thể tinh chỉnh các chức năng ghi lại hoạt động với bổ sung tối thiểu:

DB_driver.php thêm bên trong lớp:

protected $OnlyReturnQuery = false; 
public function onlyReturnQuery($return = true) 
{ 
    $this->OnlyReturnQuery = $return; 
} 

chức năng tìm truy vấn (... và thêm vào đầu rất:

if ($this->OnlyReturnQuery) { 
     $this->OnlyReturnQuery = false; 
     return $sql; 
    } 

và cuối cùng trong DB_active_rec.php thêm chức năng:

public function insert_or_update($table='', $data=array()) 
{ 
    $this->onlyReturnQuery(); 
    $this->set($data); 
    $insert = $this->insert($table); 
    $this->onlyReturnQuery(); 
    $this->set($data); 
    $update = $this->update($table); 
    $update = preg_replace('/UPDATE.*?SET/',' ON DUPLICATE KEY UPDATE',$update); 
    return $this->query($insert.$update); 
} 

Bây giờ bạn có thể sử dụng nó làm:

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

Ưu điểm: sử dụng tất cả các hoạt động xác nhận kỷ lục Nhược điểm: nó không phải là tốt nhất (các hợp nhất) cách mở rộng chức năng, bởi vì nếu bạn đang có kế hoạch để cập nhật những tập tin này, bạn sẽ phải làm lại thủ tục .

43

Bạn có thể thêm câu lệnh "ON DUPLICATE" mà không sửa đổi bất kỳ tệp lõi nào.

$sql = $this->db->insert_string('table', $data) . ' ON DUPLICATE KEY UPDATE duplicate=LAST_INSERT_ID(duplicate)'; 
$this->db->query($sql); 
$id = $this->db->insert_id(); 

Tôi hy vọng nó sẽ giúp ai đó.

+0

có nó đã giúp :) – Nishant

+0

Đây là giải pháp sạch nhất cho đến khi CI không thêm điều này. Bỏ phiếu lên o/ – Nemke

+0

Điều đáng ngờ là vì họ bỏ hỗ trợ: (http://ellislab.com/blog/entry/ellislab-seeking-new-owner-for-codeigniter – Shaffe

0

Tiếp theo đoạn nối với nhau bằng Pickett, tôi thực hiện một vài thay đổi để:

1) Cập nhật nó để sử dụng Query Builder mới (CI 3), trước đây gọi là Active Record.

2) Bây giờ bạn có thể chuyển một mảng kết hợp (key => value) hoặc một mảng các mảng kết hợp. Ở dạng thứ hai, nó thực hiện một bản cập nhật đa.

Tôi chỉ thử nghiệm bằng mysqli và nó hoạt động tốt.

Đoạn mã này nằm trong hệ thống/cơ sở dữ liệu/trình điều khiển/mysqli/mysqli_driver.php

function _duplicate_insert($table, $values) 
{ 
    $updatestr = array(); 
    $keystr = array(); 
    $valstr = array(); 

    foreach($values as $key => $val) 
    { 
     $updatestr[] = $key." = ".$val; 
     $keystr[] = $key; 
     $valstr[] = $val; 
    } 

    $sql = "INSERT INTO ".$table." (".implode(', ',$keystr).") "; 
    $sql .= "VALUES (".implode(', ',$valstr).") "; 
    $sql .= "ON DUPLICATE KEY UPDATE ".implode(', ',$updatestr); 

    return $sql; 
} 

function _multi_duplicate_insert($table, $values) 
{ 
    $updatestr = array(); 
    $keystr = array(); 
    $valstr = null; 
    $entries = array(); 

    $temp = array_keys($values); 
    $first = $values[$temp[0]]; 

    foreach($first as $key => $val) 
    { 
     $updatestr[] = $key." = VALUES(".$key.")"; 
     $keystr[] = $key; 
    } 

    foreach($values as $entry) 
    { 
     $valstr = array(); 
     foreach($entry as $key => $val) 
     { 
      $valstr[] = $val; 
     } 
     $entries[] = '('.implode(', ', $valstr).')'; 
    } 

    $sql = "INSERT INTO ".$table." (".implode(', ',$keystr).") "; 

    $sql .= "VALUES ".implode(', ',$entries); 
    $sql .= "ON DUPLICATE KEY UPDATE ".implode(', ',$updatestr); 

    return $sql; 
} 

Và điều này đi vào các tập tin /system/database/DB_query_builder.php:

function on_duplicate($table = '', $set = NULL) 
{ 
    if (! is_null($set)) 
    { 
     $this->set($set); 
    } 

    if (count($this->qb_set) == 0) 
    { 
     if ($this->db_debug) 
     { 
      return $this->display_error('db_must_use_set'); 
     } 
     return FALSE; 
    } 

    if ($table == '') 
    { 
     if (! isset($this->qb_from[0])) 
     { 
      if ($this->db_debug) 
      { 
       return $this->display_error('db_must_set_table'); 
      } 
      return FALSE; 
     } 

     $table = $this->qb_from[0]; 
    } 

    $is_multi = false; 
    foreach (array_keys($set) as $k => $v) { 
     if ($k === $v) { 
      $is_multi = true; //is not assoc 
      break; 
     } 
    } 

    if($is_multi) 
    { 
     $sql = $this->_multi_duplicate_insert($this->protect_identifiers($table, TRUE, NULL, FALSE), $this->qb_set); 
    } 
    else 
    { 
     $sql = $this->_duplicate_insert($this->protect_identifiers($table, TRUE, NULL, FALSE), $this->qb_set); 
    } 

    $this->_reset_write(); 
    return $this->query($sql); 
} 

Sau đó, bạn có thể làm điều này cho một hàng chèn đơn/cập nhật:

$this->db->on_duplicate('table', array('column1' => 'value', 'column2' => 'value')); 

Hoặc điều này cho một chèn/cập nhật đa:

$this->db->on_duplicate('table', array(
    array('column1' => 'value', 'column2' => 'value'), 
    array('column1' => 'value', 'column2' => 'value') 
)); 
3

Quá trình làm việc dưới đây cho tôi trong CodeIgniter 3.0.6

public function updateOnDuplicate($table, $data) { 
    if (empty($table) || empty($data)) return false; 
    $duplicate_data = array(); 
    foreach($data AS $key => $value) { 
     $duplicate_data[] = sprintf("%s='%s'", $key, $value); 
    } 

    $sql = sprintf("%s ON DUPLICATE KEY UPDATE %s", $this->db->insert_string($table, $data), implode(',', $duplicate_data)); 
    $this->db->query($sql); 
    return $this->db->insert_id(); 
} 
2

Dưới đây là một đoạn mã tôi sử dụng mọi để cập nhật trên các bản sao:

$sql = "insert into table_name (id, name) values(".$id.",'".$name."') on duplicate key update id=".$id.",name='".$name."'"; 
//Executing queries 
$result = $this->db->query($sql, array($id, $name)); 

Lưu ý: Cột id phải chính hoặc duy nhất

0

Sử dụng $this->db->query() và thông số, đây là cách tôi thực hiện. 4 tham số đầu tiên dành cho phần chèn và ba thông số cuối được lặp lại cho phần on duplicate key update.

$sql = "insert into application_committee ". 
     "(application_id, member1_id, member2_id, member3_id) values (?, ?, ?, ?)". 
     " on duplicate key update member1_id = ?, member2_id = ?, member3_id = ?"; 

$this->db->query($sql, array($appid, $member_1, $member_2, $member_3, 
       $member_1, $member_2, $member_3); 
Các vấn đề liên quan