1

我正在构建一个函数,用于根据四个参数过滤一些记录:$codigo$anno和. 这是我到现在为止的构建:$term$comite_tecnico

public function filtrarNorma($codigo = null, $anno = null, $term = null, $comite_tecnico = null)
{
    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb
            ->select('n')
            ->from("AppBundle:Norma", "n");

    if ($codigo != NULL) {
        $qb->where($qb->expr()->like('n.numero', ':codigo'));
        $qb->setParameter('codigo', '%' . $codigo . '%');
    }

    if ($anno != NULL) {
        $qb->orWhere($qb->expr()->like('n.anno', ':anno'));
        $qb->setParameter('anno', '%' . $anno . '%');
    }

    if ($term != NULL) {
        $qb->orWhere($qb->expr()->like('n.nombre', ':term'));
        $qb->setParameter('term', '%' . $term. '%');
    }

    if ($comite_tecnico != NULL) {
        $qb->orWhere($qb->expr()->like('n.comite_tecnico', ':comite_tecnico'));
        $qb->setParameter('comite_tecnico', '%' . $comite_tecnico . '%');
    }

    return $qb->getQuery()->getResult();
}

每当我尝试执行查询时,都会收到此错误:

执行 'SELECT n0_.numero AS numero0, n0_.anno AS anno1, n0_.id AS id2, n0_.nombre AS nombre3, n0_.activo ASactivo4, n0_.comite_tecnico_id AS comite_tecnico_id5 FROM nomencladores.norma n0_ WHERE n0_ 时发生异常。喜欢?或 n0_.anno LIKE ?带参数 ["34", 45]:

SQLSTATE [42883]:未定义函数:7 错误:运算符不存在:整数~~未知第 1 行:...dores.norma n0_ WHERE n0_.numero LIKE $1 OR n0_.anno LIKE $2 ^ 提示:没有运算符匹配给定名称和参数类型。您可能需要添加显式类型转换。

这告诉我,在将其中一些参数发送到 PgSQL DB 并执行查询以获得结果之前,我需要转换其中的一些参数,但我的问题是,我如何在 Doctrine2 DQL 上做到这一点?这是可能的?任何解决方法或技巧或其他什么?我找到了这个文档,但不知道哪个功能适用以及如何应用,任何人都可以给我一些帮助或建议吗?

使用新测试进行编辑

在用户提出建议后,我对代码进行了一些更改,现在它看起来像:

public function filtrarNorma($codigo = null, $anno = null, $term = null, $comite_tecnico = null)
{
    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb
            ->select('n')
            ->from("AppBundle:Norma", "n");

    if ($codigo != NULL) {
        $qb->where($qb->expr()->like('n.numero', ':codigo'));
        $qb->setParameter('codigo', '%'.$codigo.'%', PDO::PARAM_STR);
    }

    if ($anno != NULL) {
        $qb->orWhere($qb->expr()->like('n.anno', ':anno'));
        $qb->setParameter('anno', $anno, PDO::PARAM_INT);
    }

    if ($term != NULL) {
        $qb->orWhere($qb->expr()->like('n.nombre', ':term'));
        $qb->setParameter('term', '%'.$term.'%', PDO::PARAM_STR);
    }

    if ($comite_tecnico != NULL) {
        $qb->orWhere($qb->expr()->like('IDENTITY(n.comite_tecnico)', ':comite_tecnico'));
        $qb->setParameter('comite_tecnico', '%'.$comite_tecnico.'%', PDO::PARAM_INT);
    }

    return $qb->getQuery()->getResult();
}

但再一次,得到同样的错误:

执行 'SELECT n0_.numero AS numero0, n0_.anno AS anno1, n0_.id AS id2, n0_.nombre AS nombre3, n0_.activo ASactivo4, n0_.comite_tecnico_id AS comite_tecnico_id5 FROM nomencladores.norma n0_ WHERE n0_ 时发生异常。喜欢?或 n0_.anno LIKE ?带参数 ["%4%", "4"]:

SQLSTATE [42883]:未定义函数:7 错误:运算符不存在:整数~~未知第 1 行:...dores.norma n0_ WHERE n0_.numero LIKE $1 OR n0_.anno LIKE $2 ^ 提示:没有运算符匹配给定名称和参数类型。您可能需要添加显式类型转换。

正如您可能注意到的那样,在这种情况下,参数按原样传递:["%4%", "4"]但是为什么会出错?仍然没有到达它的位置

另一个测试

因此,使用 Doctrine Query Builder 并应用一些 Doctrine Query Language 我将查询从上面的代码移到了这个:

    $em = $this->getEntityManager();
    $query = $em->createQuery("SELECT n from AppBundle:Norma n WHERE n.numero LIKE '%:codigo%' OR n.anno LIKE '%:anno%' OR n.nombre LIKE '%:term%' OR IDENTITY(n.comite_tecnico) LIKE '%:comite_tecnico%'");
    $query->setParameters(array(
            'codigo' => $codigo,
            'anno' => $anno,
            'term' => $term,
            'comite_tecnico' => $comite_tecnico
        ));

    return $query->getResult();

但在这种情况下,我收到以下消息:

无效的参数号:绑定变量的数量与标记的数量不匹配

如果查询是通过OR应该是四个参数需要的吗?

4

4 回答 4

1

你的第一次尝试实际上一直对我有用。您可以使用 strval()' 转换整数。

'%' . strval($anno) . '%';
于 2014-11-12T01:29:30.273 回答
1

经过深入研究,我找到了解决问题的方法,也想与他人分享。我还要感谢@ErwinBrandstetter、@b.b3rn4rd 的时间和支持以及@Pradeep,这最终给了我研究的想法并最终解决了问题,我通过在 PostgreSQL 中启用隐式转换支持来做到这一点。

因此,为了启用隐式转换,您必须在连接到template1数据库时在 PostgreSQL 控制台中执行以下命令,以便之后创建的任何数据库都带有所需的 CAST(如果您的数据库已经创建,请在数据库中执行命令) :

CREATE FUNCTION pg_catalog.text(integer) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int4out($1));';
CREATE CAST (integer AS text) WITH FUNCTION pg_catalog.text(integer) AS IMPLICIT;
COMMENT ON FUNCTION pg_catalog.text(integer) IS 'convert integer to text';

CREATE FUNCTION pg_catalog.text(bigint) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int8out($1));';
CREATE CAST (bigint AS text) WITH FUNCTION pg_catalog.text(bigint) AS IMPLICIT;
COMMENT ON FUNCTION pg_catalog.text(bigint) IS 'convert bigint to text';

就是这样,在我正在使用的当前数据库以及template1未来的数据库上运行它并在我的代码上保持如下条件后,一切正常且没有任何错误:

if ($codigo != null) {
    $qb->where($qb->expr()->like('n.numero', ':codigo'));
    $qb->setParameter('codigo', '%'.$codigo.'%', PDO::PARAM_STR);
}

if ($anno != null) {
    $qb->orWhere($qb->expr()->like('n.anno', ':anno'));
    $qb->setParameter('anno', '%'.$anno.'%', PDO::PARAM_STR);
}

if ($term != null) {
    $qb->orWhere($qb->expr()->like('n.nombre', ':term'));
    $qb->setParameter('term', '%'.$term.'%', PDO::PARAM_STR);
}

if ($comite_tecnico != null) {
    $qb->orWhere($qb->expr()->like('IDENTITY(n.comite_tecnico)', ':comite_tecnico'));
    $qb->setParameter('comite_tecnico', '%'.$comite_tecnico.'%', PDO::PARAM_STR);
}

编码快乐!!

于 2014-11-12T21:02:24.743 回答
0

我认为在您最后一次尝试中,原始 SQL 字符串应如下所示:

$query = $em->createQuery("SELECT n.*
    FROM  nomencladores.norma n
    WHERE n.numero LIKE '%' || :codigo || '%' OR
          cast(n.anno AS text) LIKE '%' || :anno || '%' OR
          n.nombre LIKE '%' || :term || '%' OR
          IDENTITY(n.comite_tecnico) LIKE '%' || :comite_tecnico || '%'");

这里没有其他列吗textvarchar也投吧
不知道IDENTITY()功能。Doctrine 的溢出效应?
不过,我对Doctrine知之甚少。

于 2014-11-13T12:30:08.763 回答
-1

你试图LIKE在一个整数上使用,这是没有意义的。

将整数转换为其文本表示形式。这可能有效:

$qb->where($qb->expr()->like('CAST(n.numero AS text)', ':codigo'));
于 2014-11-13T00:31:40.950 回答