8

从逻辑上讲,在 SQL 中,我们可以使用 JOINS 从表中删除数据,例如

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;

与上述查询等效的 CodeIgniter 是什么?

CodeIgniter 是否支持带连接的删除查询?

4

4 回答 4

4

必须使用Active Records吗?

下面的查询将执行其他操作。

$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));
于 2012-05-14T10:14:43.090 回答
4

你不能用 CodeIgniter 的 Active Record 类来做到这一点。它不支持删除查询中的联接。您必须使用$this->db->query()Robin Castlin 提到的执行查询。

以下代码取自核心文件。它是生成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;
}

如您所见,其中没有指定插入JOIN子句的任何内容。

于 2012-05-14T10:48:24.200 回答
1

我有同样的问题,连接被忽略:

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

所以我这样做了:

$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);
于 2017-01-25T14:38:10.277 回答
0

您可以这样做,而不是重写整个 SQL:

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

通过这种方式,您可以保留 Query Builder(也称为 Active Records)中的好东西,并拥有自定义的自由。我认为,这很安全,因为$sql字符串总是以DELETE. 当然,您可以将其包装到一个函数中作为快捷方式。

于 2017-03-17T09:36:40.450 回答