我正在开发一个CakePHP 3.0后端,我有以下表格:' prescriptions '和' profils '(名字是法语)。
'处方'的外键指向“个人资料”: prescriptions.profils_id 。
'profils'有两个可以搜索的字段:'nom'和'prenom'
这种关系已被宣布为:
class PrescriptionsTable extends Table
{
public function initialize(array $config)
{
$this->table('prescriptions');
$this->belongsTo('Profils', [
'foreignKey' => 'profils_id',
]);
}
}
class ProfilsTable extends Table
{
public function initialize(array $config)
{
$this->table('profils');
$this->hasMany('Prescriptions', [
'foreignKey' => 'profils_id',
]);
}
}
PrescriptionsController 具有搜索操作,用户可以在其中设置各种过滤器。我正在处理的那些允许他在拥有该处方的人(Profil)的名字的子串之后搜索处方。
因此,' al '可以匹配'Albert Dupont'或'Marc Vidal',但不能匹配'EugèneBrun'。同样,' ert dup '应匹配'Albert Dupont'(作为' ont Al '应该',但这是另一个故事)。
search() 方法的查询行如下:
$q1 = $this->Prescriptions->find()->where(['Prescriptions.users_id = ' . $userId]);
$q1->matching('Profils', function ($q) use($filter) {
return $q->where(["CONCAT(Profils.prenom, ' ', Profils.nom) like" => "%$filter%"]);
});
[...]
return $q1->select(['id'])->toArray();
不幸的是,当我运行查询时,CakePHP会抛出以下错误:
错误:SQLSTATE [42S22]:找不到列:1054未知列 'on clause'中的'profils.nom'
我想检查查询对象,所以我尝试了:
$q1->matching('Profils', function ($q) use($filter) {
return $q->where(["CONCAT(Profils.prenom, ' ') like" => "%$filter%"]);
这显然不是一个非常有趣的CONCAT,但它确实有效。当我使用两个字段时,错误才会上升:第二个字段不使用别名Profils,而是使用表名'profils'。
我已经坚持这个错误几个小时了,我会很感激我在这里做错了什么。
答案 0 :(得分:1)
您正在使用的语法是支持
等结构TableAlias.column SQL_EXPRESSION
编译器将小写表达式部分,即在可能的TableAlias.column
标识符之后找到的所有内容,因此在您的情况下CONCAT(Profils.prenom,
将被视为标识符,其余部分将被视为通过空格' ', Profils.nom) like
被视为表达式(两者都没有被检查有效性),因此被小写,并且就是它发生的地方,最终查询将查找profils.nom
,它不存在,别名为Profils
。
您应该使用正确的表达式,它们是可移植的,可组合的,并且支持值绑定。
CakePHP附带了对各种SQL功能的支持,包括CONCAT
。它还支持可以与其他表达式组合的各种比较表达式,即您可以简单地将concat
函数表达式传递给like
比较表达式,您应该很好:
return $q
->where(function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) use($filter) {
return $exp
->like(
$query->func()->concat([
'Profils.prenom' => 'identifier',
' ',
'Profils.nom' => 'identifier'
]),
"%$filter%",
'string'
);
});
另见