Symfony2.3中使用IN语句的原始SQL查询

4
我正在尝试使用Doctrine EntityManager运行原始SQL查询,用于IN子句,如下所示。
    $idSArray  = Array ( [0] => 1 [1] => 2 )

    $stmt = $this->getDoctrine()->getEntityManager()
    ->getConnection()
    ->prepare('SELECT t1.id , t1.name , t2.start_date , t2.end_date 
    FROM table1 t1 , table2 t2 
    WHERE t1.id = t2.matchId AND  t1.id IN (:ids)');


    $params = array(
      'ids'  => implode( ",", $idSArray )
    );
    $stmt->execute($params);
    $results = $stmt->fetchAll();

但是我只能得到ID = 1的结果。如果我将WHERE IN条件硬编码为

     WHERE t1.id = t2.matchId AND  t1.id IN (1,2)');

然后获取这两个ID的结果。有人能告诉我在传递$params数组时我做错了什么吗?我还打印了implode的结果,输出为1,2。所以我找不到错误,也不知道如何使用IN语句执行原始SQL查询。


3个回答

17

所以你至少犯了两个错误。第一个是 @Alarid 所说的:不应将数组implode。第二个是在运行准备好的语句时,必须使用DoctrineDBAL类型转换来处理IN子句

最后,你的查询应该是这样的:

$stmt = $this->getDoctrine()->getEntityManager()
        ->getConnection()
        ->prepare('SELECT t1.id , t1.name , t2.start_date , t2.end_date
        FROM table1 t1 , table2 t2
        WHERE t1.id = t2.matchId AND  t1.id IN (:ids)');

$stmt->bindValue('ids', $idSArray, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY);
$stmt->execute();

或者选择另一个选项:

$stmt = $this->getDoctrine()->getEntityManager()
    ->getConnection()
    ->executeQuery('SELECT t1.id , t1.name , t2.start_date , t2.end_date
        FROM table1 t1 , table2 t2
        WHERE t1.id = t2.matchId AND  t1.id IN (:ids)',
        array('ids' => $idSArray),
        array('ids' => \Doctrine\DBAL\Connection::PARAM_INT_ARRAY)
    )
;

3
您第一个选择目前存在"Array to string conversion"错误。第二个选择可行。手册中也有说明:参数列表仅适用于Doctrine\DBAL\Connection::executeQuery()和Doctrine\DBAL\Connection::executeUpdate(),而不适用于预处理语句的绑定方法。 - 10us

1

@Hast,你发布的第二个代码块有效。我会添加一个新答案,以便未来的查看者可以参考...

$ids = [1,2];

$sql = "SELECT t1.id , t1.name , t2.start_date , t2.end_date
        FROM table1 t1 , table2 t2
        WHERE t1.id = t2.matchId AND  t1.id IN (?)";

$stmt = $this->getEntityManager()->getConnection()->executeQuery(
        $sql,
        [$ids],
        [\Doctrine\DBAL\Connection::PARAM_INT_ARRAY] // for an array of strings use PARAM_STR_ARRAY
    );

$data = $stmt->fetchAll();

0

你必须让你的数组保持为数组,不要将其合并。

$params = array(
   'ids'  => $idSArray
);

2
在这种情况下,我会收到错误通知:在......\vendor\doctrine\dbal\lib\Doctrine\DBAL\Statement.php的第138行中将数组转换为字符串。 - xyz
你能告诉我更多关于这个错误的信息吗?我记不清楚怎么做了,但我认为你不需要将数组implode。请参考http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html,第4.2.2点。 - Alarid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接