原则:具有 LIKE 条件的 Multiple orWhere

saj*_*ili 2 php sql symfony doctrine-orm

使用具有结构的表:

id              | count
/string/id1     | 3 
/string/id1/r1  | 2
/string/id1/r2  | 1 
/string/id2/r1  | 2
/string/id2     | 3 
/string/id2/r1  | 2
/string/id3/r1  | 5
Run Code Online (Sandbox Code Playgroud)

我想选择id中需要子字符串的所有行。
即我需要 id 中有子字符串的所有行: /string/id1/string/id2

查询应该很简单 - 简单的 sql:

select * from table_name where id LIKE '/string/id1%' OR id LIKE '/string/id2%';
Run Code Online (Sandbox Code Playgroud)

结果应该是:

id              | count
/string/id1     | 3 
/string/id1/r1  | 2
/string/id1/r2  | 1
/string/id2/r1  | 2
/string/id2     | 3 
/string/id2/r1  | 2
Run Code Online (Sandbox Code Playgroud)

不幸的是,如果您尝试在 symfony 和doctrine2 中使用相同的查询:

$ids = array('/string/id1', '/string/id2');

$query = $this->createQueryBuilder('r')
              ->select('r');
foreach ($ids as $id) {
    $query->orWhere("r.linkedId LIKE :id ")
        ->setParameter('id', $id."%");
}
$plainQuery = $query->getQuery()->getSQL();
$results = $query->getQuery()->getResult();
Run Code Online (Sandbox Code Playgroud)

普通查询看起来与 相同select * from table_name where id LIKE '/string/id1%' OR id LIKE '/string/id2%';,但结果却不同。

结果仅包含 ids 中最后一项的行 - /string/id2

id              | count
/string/id2/r1  | 2
/string/id2     | 3 
/string/id2/r1  | 2
Run Code Online (Sandbox Code Playgroud)

怎么解决呢?我的错误在哪里?您有什么建议吗?

Jov*_*vic 5

我不能确定,但​​这在我看来就像与参数标识符的冲突。

这就是你想要做的:

  • 构造基本SELECT * FROM table_name语句
  • 附加WHERE r.linkedId LIKE :id
  • 将参数值设置id/string/id1%
  • 附加OR r.linkedId LIKE :id
  • 将参数值设置id/string/id2%(覆盖之前的值)<-- 错误

基本上,您是在告诉 Doctrine 用新值覆盖先前定义的id参数值。

您可以轻松克服这个问题。只需添加$i参数名称即可

foreach ($ids as $i => $id) { 
    // $i here has the value of 0,1,2, etc...

    $query->orWhere("r.linkedId LIKE :id$i" ) // append $i
        ->setParameter("id$i", $id."%"); // but also append it here 
}
Run Code Online (Sandbox Code Playgroud)

请务必使用双引号,或连接 ( "id" . $i) ;)