我正在CakePHP 3.0后端工作,我有以下表:'处方'和'概要文件'(名称是法语)。
' prescritions '有一个指向' profiles '的外键: prescritions .profils_id。
"profiles"有两个可以搜索的字段:"nom"answers"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有一个搜索操作,用户可以在其中设置各种过滤器。我正在研究的那些允许他搜索处方后的人(配置文件)的名字的子字符串拥有该处方。
因此,'al'可以匹配'Albert Dupont'或'Marc Vidal',但不能匹配' eug
$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]: Column not found: 1054 Unknown Column的资料。Nom ' in 'on子句
我想检查查询对象,所以我尝试:
$q1->matching('Profils', function ($q) use($filter) {
return $q->where(["CONCAT(Profils.prenom, ' ') like" => "%$filter%"]);
显然不是一个很有趣的CONCAT,但它可以工作。只有当我使用两个字段时,错误才会上升:第二个字段不使用别名Profils,而是使用表名"profiles"。
我已经被这个错误困了好几个小时了,我将感谢任何关于我在这里做错了什么的见解。
使用的语法不支持
你正在使用的语法是用来支持像
这样的结构的。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'
);
});
参见
- Cookbook>数据库访问&ORM>查询生成器>使用SQL函数
- Cookbook>数据库访问&ORM>查询生成器>高级条件
- API> 'Cake'Database'Expression'QueryExpression::like()
- API> 'Cake'Database'FunctionsBuilder::concat()