2012-05-14 22 views
7

Lógicamente en SQL podemos eliminar datos de tablas con JOINS, p. Ej.Codeigniter eliminando datos con tablas de uniones

DELETE clb_subscriber_group_mapping .* FROM clb_subscriber_group_mapping 
INNER JOIN clb_driver_group ON (clb_driver_group.id = clb_subscriber_group_mapping.driver_group_id) 
INNER JOIN clb_company ON (clb_company.id = clb_driver_group.company_id) 
WHERE clb_company.id = 256 AND clb_subscriber_group_mapping.subscriber_id = 1784; 

¿Cuál será el equivalente de CodeIgniter de la consulta anterior?

¿Admite CodeIgniter Eliminar consulta con combinaciones?

Respuesta

4

¿Tiene tiene para usar Active Records?

Esto a continuación query hará lo contrario.

$int_company_id = 256; 
$int_subscriber_id = 1784; 

$this->db->query(" 
DELETE clb_subscriber_group_mapping .* FROM clb_subscriber_group_mapping 
INNER JOIN clb_driver_group ON (clb_driver_group.id = clb_subscriber_group_mapping.driver_group_id) 
INNER JOIN clb_company ON (clb_company.id = clb_driver_group.company_id) 
WHERE clb_company.id = ? AND clb_subscriber_group_mapping.subscriber_id = ?; 

", array($int_company_id, $int_subscriber_id)); 
+1

Oye, no quiero utilizar el método query(). Quiero usar $ this-> db-> join(), $ this-> db-> delete() Tengo mi punto? –

4

No se puede hacer eso con la clase Active Record de CodeIgniter. No admite combinaciones en la consulta de eliminación. Tendrá que ejecutar la consulta usando $this->db->query() como lo menciona Robin Castlin.

El siguiente código está tomado de los archivos del núcleo. Es uno de los componentes internos, que genera la consulta DELETE.

function _delete($table, $where = array(), $like = array(), $limit = FALSE) 
{ 
    $conditions = ''; 

    if (count($where) > 0 OR count($like) > 0) 
    { 
     $conditions = "\nWHERE "; 
     $conditions .= implode("\n", $this->ar_where); 

     if (count($where) > 0 && count($like) > 0) 
     { 
      $conditions .= " AND "; 
     } 
     $conditions .= implode("\n", $like); 
    } 

    $limit = (! $limit) ? '' : ' LIMIT '.$limit; 

    return "DELETE FROM ".$table.$conditions.$limit; 
} 

Como se puede ver, no hay nada allí que especifica la inserción de una cláusula JOIN.

+2

Sí, pero debería ser, ojalá alguien de CI esté escuchando –

+2

Bueno, ¿por qué no lo llevas a sus foros (http://codeigniter.com/forums/)? O, tal vez su rastreador de errores (https://github.com/EllisLab/CodeIgniter/issues)? –

1

que tenían el mismo problema, la unión fue ignorada:

$r1 = $db->where("object2_type", $object_type) 
->join($object_type, "$object_type.id = object1_id", "LEFT") 
->where("$object_type.id IS NULL", null, false) 
->delete("knots"); 

así que lo hice así:

$ids = $db->select("knots.id") 
->where("object2_type", $object_type) 
->join($object_type, "$object_type.id = object1_id", "LEFT") 
->where("$object_type.id IS NULL", null, false) 
->get("knots")->result_object(); 
/* my ow function which generates a string like '1','2','3' or 0 */  
$ids_csv = $this->mh()->get_flat_items_as_csv($ids); 
$r = $db->where("knots.id IN ($ids_csv)", null, false)->delete("knots); 
1

En lugar de volver a escribir todo el SQL, puede hacerlo de esta manera:

// build query as usual... 
$this->db 
    ->from ('cookies') 
    ->join ('recipes', 'recipes.cookie = cookies.id') 
    ->where ('recipes.rating', 'BAD'); 

/* 
* get the original DELETE SQL, in our case: 
* "DELETE FROM `cookies` JOIN `recipes` ON `recipes`.`cookie`=`cookies`.`id` WHERE `recipes`.`rating`='BAD'" 
*/ 
$sql = $this->db->get_compiled_delete ('cookies'); 

/* 
* insert the target table in the SQL string, to get this: 
* "DELETE `cookies` FROM `cookies` JOIN `recipes` ON `recipes`.`cookie`=`cookies`.`id` WHERE `recipes`.`rating`='BAD'" 
*/ 
$target = $this->db->escape_identifiers ('cookies'); // just to be safe 
$sql = substr_replace ($sql, " $target", 6, 0); // note the prepended space 

// now we can run the query 
$q = $this->db->query ($sql); 

De esta manera, conserve las cosas buenas de Query Builder (también conocido como Registros activos) y tenga su libertad de costumbre ización también. Creo que es bastante seguro, ya que la cadena $sql siempre comenzará con DELETE. Puede envolver esto en una función como un atajo, por supuesto.

Cuestiones relacionadas