使用mysql用户变量的Doctrine本机查询

时间:2014-06-17 17:35:14

标签: php pdo doctrine-orm

这是我的原生查询:

$query = <<<Query
        SET @num = 0;
        SET @type = 0;
        SELECT md.*, od.id AS order_detail_id, od.erc AS od_ec,
              @num := if(@type = od.id, @num + 1, 1) AS row_number,
              @type := od.id AS dummy
        FROM bar md
        LEFT JOIN foobar mb ON md.mbi = mb.id
        LEFT JOIN barfoo od ON od.mbid = mb.id 
        WHERE od.id IN ($where)
        AND (od.status = $statusQueued OR od.status = $statusProcessing)
        GROUP BY md.id
        HAVING row_number <= od.erc
        ORDER BY md.qt ASC
        LIMIT 0, 1000
Query;

$nativeQuery = $this->_em->createNativeQuery($query, $rsm);

当我执行它时,PDO会感到沮丧,并向我抛出错误:

  

[PDOException] SQLSTATE [HY000]:常规错误

没有更多信息。

然而,当我摆脱前两行(&#34; SET&#34;)时,查询运行(但返回错误的结果,因为在这种情况下必须初始化变量)。如何强制PDO正确运行? (通过PMA运行时效果很好)

2 个答案:

答案 0 :(得分:3)

似乎最优雅的解决方案是利用MySQL替代初始化语法:

$query = <<<Query
        SELECT md.*, od.id AS order_detail_id, od.erc AS od_ec,
              @num := if(@type = od.id, @num + 1, 1) AS row_number,
              @type := od.id AS dummy
        FROM (SELECT @num := 0, @type := 0) init, bar md
        LEFT JOIN foobar mb ON md.mbi = mb.id
        LEFT JOIN barfoo od ON od.mbid = mb.id 
        WHERE od.id IN ($where)
        AND (od.status = $statusQueued OR od.status = $statusProcessing)
        GROUP BY md.id
        HAVING row_number <= od.erc
        ORDER BY md.qt ASC
        LIMIT 0, 1000
Query;

答案 1 :(得分:1)

我遇到同样的问题,试图在一次通话中运行多个查询(在我的情况下,它是关于使用SQL_CALC_FOUND_ROWS及其伙伴FOUND_ROWS())。

学说无法解决这个问题。我不知道官方的原因,但在我看来,它可能是一个安全问题(因为EM的呼叫随后可以进行基本的查询注入)。

仍然在我看来,处理这个问题最优雅的方法是使用EM的交易模式:

//fetch PDO-ish adapter
$conn = $em->getConnection();
//open an atomic sequence
$conn->beginTransaction();
//do your stuff
$conn->executeQuery('SET @...');
$stmt = $conn->executeQuery('SELECT stuff using @vars');
//commit the atomic sequence
$conn->commit();
//fetch the result, could be useful ;)
$data = $conn->fetchAll();

希望这有帮助! (并适用于您的情况......)