Php 根据条令中的条件更新某些字段

Php 根据条令中的条件更新某些字段,php,sql,symfony,doctrine-orm,Php,Sql,Symfony,Doctrine Orm,我创建了一个Symfony 2捆绑包,它支持用户之间的私人消息。我让他们能够从收件箱或sent文件夹向垃圾箱发送消息。消息将通过收件人和发件人分别标记的istrash和isSTrash字段标记为垃圾。这是因为,作为数据库中的同一条消息,如果这里有一个字段,一个用户将其标记为垃圾,那么另一个用户也会将其标记为垃圾 现在,我想让他们也可以从垃圾箱文件夹中删除他们。消息不会被删除,但标记类似于垃圾消息,只是它们永远从标准用户视图中消失。我在这样标记它们时遇到问题,因为我必须标记用户发送和接收的两条消息

我创建了一个Symfony 2捆绑包,它支持用户之间的私人消息。我让他们能够从
收件箱
sent
文件夹向
垃圾箱
发送消息。消息将通过收件人和发件人分别标记的
istrash
isSTrash
字段标记为垃圾。这是因为,作为数据库中的同一条消息,如果这里有一个字段,一个用户将其标记为垃圾,那么另一个用户也会将其标记为垃圾

现在,我想让他们也可以
从垃圾箱文件夹中删除
他们。消息不会被删除,但标记类似于垃圾消息,只是它们永远从标准用户视图中消失。我在这样标记它们时遇到问题,因为我必须标记用户发送和接收的两条消息

我在实体的存储库中进行了以下查询:

    public function delete($user, $msg)
    {
        $qb = $this->createQueryBuilder('a')
            ->update('PrivateMessageBundle:Message', 'a')
            ->where('a IN(:msg)')
            ->andwhere('a.receiver = :user AND a.isRTrash IS NOT null AND a.isRDeleted = false')->set('a.isRDeleted', true)
            ->orWhere('a.sender = :user AND a.isSTrash IS NOT null AND a.isSDeleted = false')->set('a.isSDeleted', true)
            ->setParameters(
                array('user' => $user, 'msg' => $msg)
            );
echo '<pre>';
\Doctrine\Common\Util\Debug::dump($qb->getQuery()->getSQL()); exit;
echo '</pre>';
        return $qb->getQuery();
    }

我想你需要一个
箱子。。当
构造时,但DQL中没有该构造(请参阅)。因此,您必须使用原始查询,大致如下(它是伪MySQL):

。。。或者使用两个标准查询,一个用于
isremeleted
,另一个用于
isremeleted
,就像您已经做的一样。老实说,我认为在您的情况下,这是一个非常简单的解决方案,如果您需要在六个月内再次阅读代码,它看起来更易于维护

注意:另一方面,条令中的
->set()
->when()
函数(实际上还有所有其他函数)没有遵循特定的顺序;它们只是向条令查询对象添加属性,当您调用
getQuery()
时,就会进行SQL查询。这意味着以下结构:

 ->set()->set()
 ->when()->orWhen() 
相当于:

这就是为什么您的解决方案无法工作的原因。在调用
set()
之前不需要满足任何条件(如果我不清楚,请告诉我)


是的,我发现顺序在查询中并不重要。我还查找了CASE..WHEN语句,但找不到任何更新的工作解决方案,只查找INSERT。如果不满足条件,您不应该保持isR/SDeleted值不变吗?似乎您可以错误地恢复邮件;)。不明白为什么需要检查值是否为false,因为您会将它们设置为true,对性能有影响吗?@georgeirimicuc您只需在原则中使用本机SQL查询:
return$this->getEntityManager()->getConnection()->executeQuery($SQL,$params)
使用
$sql
您的查询和
$params
参数。@tchap关于使用两个标准查询,这意味着我必须检查同一个消息数组两次。我在寻找一个替代方案。同时,我正在数组上执行foreach并检查每条消息,但单个查询将比使用ORM的foreach快得多。不,我只是指在
delete()
函数中复制您的更新查询:一个使用
->where('a.receiver=:user和a.isrrash不为null,a.isrdeted=false')->set('a.isrdeted',true)
和带有
->其中('a.sender=:user和a.isSTrash不为null,a.isSDeleted=false')->set('a.isSDeleted',true)
。这是两个
UPDATE
,而不是一个,我认为对你来说,这没什么大不了的。
UPDATE PrivateMessageBundle:Message a
SET a.isRDeleted = CASE
    WHEN a.receiver = :user AND a.isRTrash IS NOT null THEN TRUE
    ELSE a.isRDeleted = FALSE
END, 
SET a.isSSDeleted = CASE
    WHEN a.receiver = :user AND a.isRTrash IS NOT null THEN TRUE
    ELSE a.isSDeleted = FALSE
END
 ->when()->set()
 ->orwhen()->set()
 ->set()->set()
 ->when()->orWhen()