如何在连接条件中使用CONCAT和CakePHP?
我正在开发一个CakePHP 3.0后端,其中有以下表格:“处方”和“profils”(名称为法语) “处方”有一个指向“profils”的外键:处方。profils\u id “profils”有两个可以搜索的字段:“nom”和“prenom” 关系声明如下:如何在连接条件中使用CONCAT和CakePHP?,php,cakephp,Php,Cakephp,我正在开发一个CakePHP 3.0后端,其中有以下表格:“处方”和“profils”(名称为法语) “处方”有一个指向“profils”的外键:处方。profils\u id “profils”有两个可以搜索的字段:“nom”和“prenom” 关系声明如下: class PrescriptionsTable extends Table { public function initialize(array $config) { $this->tab
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',
]);
}
}
PrescriptionController有一个搜索操作,用户可以在其中设置各种过滤器。我正在处理的程序允许他在拥有处方的人的名字(Profil)的子字符串后搜索处方
因此,al可以与“阿尔伯特·杜邦”或“马克·维达尔”相提并论,但不能与“尤金·布伦”相提并论。同样地,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子句”中的“profils.nom”
我想检查查询对象,因此我尝试:
$q1->matching('Profils', function ($q) use($filter) {
return $q->where(["CONCAT(Profils.prenom, ' ') like" => "%$filter%"]);
这显然不是一个很有趣的康卡特,但它是有效的。仅当我使用两个字段时,错误才会出现:第二个字段不使用别名Profils,而是使用表名“Profils”
我已经被这个错误困扰了好几个小时了,我会很感激任何关于我在这里做错了什么的见解 所使用的语法不支持这一点
您正在使用的语法是用于支持以下结构的
TableAlias.column SQL_EXPRESSION
编译器将对表达式部分进行小写,即在可能的TableAlias.column
标识符之后找到的所有内容,因此在您的情况下CONCAT(Profils.prenom,
将被视为标识符,其余部分将被视为通过空格分隔的'',Profils.nom),如
,正被视为表达式(两个表达式都没有被检查有效性),因此被小写,这就是它发生的地方,finaly查询将查找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'
);
});
另见
中,所以是否存在您可能正在执行连接的地方并且可能失败?我可能错了,因为我没有CakePHP方面的经验,并且我必须在紧急情况下处理此代码。据我所知,这些文件的匹配()函数处理连接。Profils
表是否有一个nom
列?我必须使用“literal”而不是“identifier”,因为“identifier”类型给了我如下查询:SELECT Prescriptions.id ASPrescriptions\u id
FROM Prescriptions Prescriptions Prescriptions LEFT join Profils ON Profils.id=(Prescriptions.profils_id)其中(Prescriptions.users_id=190和(CONCAT('identifier','identifier'))类似于'%whatever%')。无论如何,感谢您的详细回答,您拯救了我的一天:o)@christophern这不应该发生,identifier
应该是一种方式,因为它支持自动引用。我已经用最新的CakePHP3.3.8测试了代码,效果很好。