CakePHP删除多个条件

时间:2015-03-19 13:12:34

标签: php cakephp cakephp-3.0

这让我很生气。为什么Cake需要使简单的事情变得过于复杂..

我希望让Cake生成看起来像这样的SQL ..

我希望运行的SQL是

DELETE `ProductVouchers` 
FROM `product_vouchers` AS `ProductVouchers`   
WHERE `ProductVouchers`.`id` = 16 
AND `ProductVouchers`.`client_id` IS NULL; 

我正在使用delete()这样的

$this->ProductVouchers->delete([
    'ProductVouchers.id'=>$id,
    'ProductVouchers.client_id'=>"NULL"
]);

日志显示

DELETE `ProductVouchers` 
FROM `product_vouchers` AS `ProductVouchers`   
WHERE `ProductVouchers`.`id` IN (16, 'NULL')

尝试

$this->ProductVouchers->delete([
   'ProductVouchers.id'=>$id,
   'ProductVouchers.client_id'=>NULL
]);

日志显示

DELETE `ProductVouchers` 
FROM `product_vouchers` AS `ProductVouchers`   
WHERE `ProductVouchers`.`id` IN (16, NULL) 

尝试:

 $this->ProductVouchers->delete([
    'ProductVouchers.id'=>$id,
    'ProductVouchers.client_id IS NULL'
 ]);

日志显示什么都没错!

编辑:

正如下面的答案所指出的,delete()方法是不正确的,因为它只接受主键作为整数。所以使用deleteAll()

 $this->ProductVouchers->deleteAll([       
   'ProductVouchers.id'=>$id,
   'ProductVouchers.client_id'=>'NULL'
 ]);

这也不会在日志中产生任何内容或任何错误。尝试:

 $this->ProductVouchers->deleteAll([
   'ProductVouchers.id'=>$id,
   'ProductVouchers.client_id'=>NULL
 ]);

这会产生......

 DELETE `ProductVouchers` 
 FROM `product_vouchers` AS `ProductVouchers`   
 WHERE `ProductVouchers`.`id` = (17)

这既错又怪(括号的意思是什么?)

5 个答案:

答案 0 :(得分:15)

Model :: delete需要一个id

删除是一种按主键值删除一行的方法。 Model::delete的方法签名不期望条件:

  

delete()public

     

删除给定ID的记录。如果没有给出ID,则使用当前ID。成功时返回true。

     

参数

     

integer | string $ id可选null - 要删除的记录的ID

     

boolean $ cascade optional true

调用传递数组时的行为是它无法正常工作(在这种情况下,条件数组的数组值被理解为id - 并用于查找 a < / em>记录删除 - 它最多会删除一行。)

Model :: deleteAll需要条件

deleteAll是一种按条件删除行的方法:

/**
 * Deletes multiple model records based on a set of conditions.
 *
 * @param mixed $conditions Conditions to match
 * @param bool $cascade Set to true to delete records that depend on this record
 * @param bool $callbacks Run callbacks
 * @return bool True on success, false on failure
 * @link http://book.cakephp.org/2.0/en/models/deleting-data.html#deleteall
 */
    public function deleteAll($conditions, $cascade = true, $callbacks = false) {

问题中对逻辑的正确调用是:

$model->deleteAll(
    [
        'ProductVouchers.id' => 16, 
        'ProductVouchers.client_id' => null
    ],
    $cascade,
    $callbacks
);

这也不会在日志中产生任何内容或任何错误

使用$cascade调用deleteAll为true(默认值)表示:

  • 查找符合条件的所有记录
  • 逐一删除

如果没有找到符合条件的记录,则不会有删除声明。

这个条件片段:

'ProductVouchers.client_id'=>'NULL'

将生成此sql:

WHERE ProductVouchers.client_id = 'NULL'

即。它将返回其中client_id为字符串“NULL”的行 - 因此没有delete语句,因为有 no 行,其client_id设置为字符串“NULL”。

这既错又怪(括号的意思是什么?)

实际上该语句是如果,如果有一条记录,主键和client_id设置为null(在id和client_id值之前会有一个select语句)。括号没有功能相关性,这两个陈述是等价的:

DELETE FROM `product_vouchers` WHERE `ProductVouchers`.`id` = (17)
DELETE FROM `product_vouchers` WHERE `ProductVouchers`.`id` = 17

如何按条件删除?

生成此sql的等价物:

DELETE FROM `product_vouchers` AS `ProductVouchers`   
WHERE `ProductVouchers`.`id` = 16 
AND `ProductVouchers`.`client_id` IS NULL; 

只需停用$cascade

即可
$model->deleteAll(
    [
        'ProductVouchers.id' => 16, 
        'ProductVouchers.client_id' => null
    ],
    false # <- single delete statement please
);

答案 1 :(得分:3)

只需阅读文档,delete method only takes the identifier in the first parameter按设计整数。

看起来Cake团队可能已经接受了数组格式,但只使用数组值来提供删除查询(因此每次忽略键并使用标识符。)

我相信您正在寻找the deleteAll method,它会接受您在问题中提供的自定义条件:

$this->ProductVouchers->deleteAll(['ProductVouchers.id'=>$id,'ProductVouchers.client_id'=>"NULL"]);

答案 2 :(得分:1)

该问题与模型$belongsTo模型中的ProductVouchers变量有关。设置此项时,我无法将标准应用于外键而不将$cascade参数设置为false,如下所示:

 $this->ProductVouchers->deleteAll([
   'ProductVouchers.id'=>$id,
   'ProductVouchers.client_id IS NULL'
 ],false);

这会生成工作SQL

DELETE `ProductVouchers` FROM `product_vouchers` AS `ProductVouchers`             
LEFT JOIN `onepulse_dev`.`clients` AS `Client`
ON (`ProductVouchers`.`client_id` = `Client`.`clients_id`)  
WHERE `ProductVouchers`.`id` = 25 AND `ProductVouchers`.`client_id` IS NULL

编辑:

按照@ AD7six的综合答案删除不必要的连接。

 $this->ProductVouchers->deleteAll([
   'ProductVouchers.id'=>$id,
   'ProductVouchers.client_id'=>NULL
 ],false);

答案 3 :(得分:1)

尝试按照:

$id = 100;
$conditions = array(
    'OR' => array(
        'ProductVouchers.id' => $id,
        'ProductVouchers.client_id IS NULL'
    )
);

$this->ProductVouchers->deleteAll($conditions);

应该创建以下SQL Query:

SELECT `ProductVouchers`.`id` FROM `cakephp2`.`ProductVouchers` AS `product_vouchers` WHERE ((`ProductVouchers`.`id` = 100) OR (`ProductVouchers`.`client_id` IS NULL)) GROUP BY `ProductVouchers`.`id`
DELETE `ProductVouchers` FROM `cakephp2`.`ProductVouchers` AS `product_vouchers` WHERE `ProductVouchers`.`id` IN (1, 8, 100)

&#34; IN(1,8,100)&#34;是前一个调用SELECT语句的结果。

答案 4 :(得分:-1)

尝试此操作以删除具有多个条件的所有内容

$this->Model->deleteAll(array('Model.field_name'=>'field_value'));