Insertar múltiples filas en CodeIgniter 2, útil para manejadores como MySQL y PostgreSQL
Este artículo lo tomé de http://codefury.net/2009/12/insert-multiple-rows-into-a-database-with-codeigniter/, pero lo he adaptado para funcionar con CI2
Paso 1: Extender la clase Model.php
En la carpeta application/core/ crear la clase MY_Model.php, el prefijo MY_ debe ser el mismo que se encuentra establecido en el archivo config.php en el elemento 'subclass_prefix'
<?php
/**
* @link http://codefury.net/2009/12/insert-multiple-rows-into-a-database-with-codeigniter/ Hacer multiples inserts
* @author KENNY KATZGRAU
*/
class MY_Model extends CI_Model
{
public function __construct()
{
parent::__construct();
}
/**
* A method to facilitate easy bulk inserts into a given table.
* @param string $table_name
* @param array $column_names A basic array containing the column names of the data we'll be inserting
* @param array $rows A two dimensional array of rows to insert into the database.
* @param bool $escape Whether or not to escape data that will be inserted. Default = true. Para otros drivers diferentes a MySQl, habría que poner FALSE
* @author Kenny Katzgrau
*/
public function insert_rows($table_name, $column_names, $rows, $escape = true)
{
/* Build a list of column names */
$columns = array_walk($column_names, array($this, 'prepare_column_name'));
$columns = implode(',', $column_names);
/* Escape each value of the array for insertion into the SQL string */
if ($escape){
array_walk_recursive($rows, array($this, 'escape_value'));
}
# asignar un table-prefix si está definido en el archivo database.php
$table_name = $this->db->dbprefix($table_name);
/* Collapse each rows of values into a single string */
$length = count($rows);
for ($i = 0; $i < $length; $i++){
$rows[$i] = implode(',', $rows[$i]);
}
/* Collapse all the rows into something that looks like
* (r1_val_1, r1_val_2, ..., r1_val_n),
* (r2_val_1, r2_val_2, ..., r2_val_n),
* ...
* (rx_val_1, rx_val_2, ..., rx_val_n)
* Stored in $values
*/
$values = "(" . implode('),(', $rows) . ")";
$sql = "INSERT INTO {$table_name} ({$columns}) VALUES {$values}";
/*
$querie_file = PATH_APP_DEBUGS . 'queries_' . date('Y-m-d') . '.log';
file_put_contents($querie_file, $sql, FILE_APPEND);
*
*/
return $this->db->simple_query($sql);
}
public function escape_value(& $value)
{
if (is_string($value)) {
$value = "'" . mysql_real_escape_string($value) . "'";
}
}
public function prepare_column_name(& $name)
{
$name = "`$name`";
}
}
Paso 2: Ejemplo A
He aquí un ejemplo para probar la inserción de varias filas en un mismo query:
class Messages extends MY_Model
{
/* Code .. */
function insert_test_data()
{
/* Prepare some fake data (10000 rows, 40,000 values total) */
$rows = array_fill(0, 10000, array(34239, 102438, "Test Message!", '2009-12-12'));
$columns = array('to_user_id', 'from_user_id', 'message', 'created');
$this->insert_rows('messages', $columns, $rows);
}
}
Paso 1: Ejemplo B
Otro ejemplo, de cómo se usaría en un método típico de un modelo en CodeIgniter:
<?php
class M_usuarios extends MY_Model
{
private $_enc_key;
protected $_usuario_id;
public function asignar_permisos()
{
$this->_usuario_id = (int) $this->input->post('sel_campo01');
$this->db
->where('usuario_id', $this->_usuario_id)
;
try {
$this->db->trans_start();
$this->db->query('LOCK TABLES t_ci_sessions LOW_PRIORITY WRITE');
$this->db->query('LOCK TABLES t_usuarios_t_submenus LOW_PRIORITY WRITE');
# primero, eliminar todos los permisos asignados
$delete = $this->db->delete('usuarios_t_submenus');
# segundo, insertar todos los permisos recién asignados
$a_columns = array('usuario_id', 'submenu_id');
$a_rows = $this->_preparar_datos_permisos($this->_usuario_id, $this->input->post('sel_campo02'));
# método insert_rows() que nosotros definimos en la clase MY_Model.php
$insert = $this->insert_rows('usuarios_t_submenus', $a_columns, $a_rows);
$this->db->query('UNLOCK TABLES');
$this->db->trans_complete();
return array('insert' => TRUE, 'mensaje' => '');
} catch (Exception $e) {
$this->db->query('UNLOCK TABLES');
$this->db->trans_complete();
return array('insert' => FALSE, 'mensaje' => $e->getMessage());
}
}
private function _preparar_datos_permisos($usuario_id, $permisos)
{
$filas = array();
foreach ($permisos as $_submenu_id){
$filas[] = array($usuario_id, $_submenu_id);
}
return $filas;
}
}
Eso es todo, espero que les sea de utilidad.
No hay comentarios:
Publicar un comentario