需要帮助将查询从 PostgreSQL 转换为 CakePHP

Need help converting a query from PostgreSQL to CakePHP

我有一个查询在我的 PostgreSQL 数据库中执行时运行良好,但我无法在我的控制器中运行它。

这是查询:

SELECT id, nume, prenume FROM cirrus.personal WHERE unaccent(nume) ILIKE '%bala%' OR unaccent(prenume) ILIKE '%bala%';

这个查询的特别之处在于我使用了我的 PostgreSQL 数据库的 unaccent() 扩展,因为当我搜索一个人的名字时,我需要它对 'a''ă'.

等特殊字符不敏感

我在 PersonalController.php 中的查询如下:

$personalTemp = $this->Personal->find('all', ['fields' => ['id', 'nume', 'prenume']])
                ->where(['OR' => [['Personal.nume ilike' => "%" . $term . "%"], 
                                  ['Personal.prenume ilike' => "%" . $term . "%"]]]);

我尝试了多种将 unaccent() 放入该查询中的方法,例如将其添加到 unaccent(Personal.nume)"unaccent(%" . $term . "%)",但其中的 none 与SQL 我正在尝试完成的查询。

如有任何建议,我们将不胜感激。

编辑:

我已经成功地在我的控制器中创建了所需的查询。它看起来像这样:

    $personalTemp = $this->Personal->find('all', ['fields' => [
                                'id' => 'id',
                                'nume' => 'nume',
                                'prenume' => 'prenume'
                                ]])
                        ->where(['OR' => [ 
     ['public.unaccent(nume) ilike public.unaccent(\'%'. $term . '%\') '],
     ['public.unaccent(prenume) ilike public.unaccent(\'%'. $term . '%\') ']]]);`

但是现在 CakePhp 无法识别 unaccent() 函数。任何人都可以帮我吗?

试试这个

    $this->Personal->find('all', array(
        'fields' => array(
            'Personal.id',
            'Personal.nume',
            'Personal.prenume'
        ),
        'conditions' => array(
            'OR' => array(
                'unaccent(nume) LIKE \'%bala%\''
                'unaccent(nume) LIKE \'%bala%\''
            )
        )
    ))

似乎 unaccent 扩展设置为 public 架构。 尝试将其设置为您的模式:

ALTER EXTENSION unaccent
  SET SCHEMA your_schema;

根据Postgresql docs

SET SCHEMA

This form moves the extension's objects into another schema.

根据文档,您需要使用 bind 来避免 sql 注入问题

https://book.cakephp.org/3.0/en/orm/query-builder.html#binding-values

试试这个

$orWhere = [
            "unaccent(nume) ilike '%'||unaccent(:search)||'%' ",
            "unaccent(prenume) ilike '%'||unaccent(:search)||'%' ",
        ];
$qry->bind(':search', $search, 'string');
$qry->where(['OR' => $orWhere]);