Doctrine Native SQL,不同的结果

问题描述 投票:0回答:1

我需要帮助。我有一个原始 SQL 查询 (MySql),它根据制造商的权重计算我的产品排名。 这两个表可以恢复为:

产品

身份证 合作伙伴ID
11 1
12 3
13 2
14 3
15 1

合作伙伴

身份证 位置
1 2
2 3
3 1

我的查询是这样的:

INSERT INTO product_rank (product_id,partner_id,weight,`rank`)
SELECT g.product_id, g.partner_id, g.weight, g.rank FROM (SELECT (@rank:=@rank +1) AS rank, m.* FROM 
(SELECT x.id AS product_id, x.partner_id, x.weight FROM 
    (
        SELECT
            t.id,
            t.partner_id,
            p.position,
            CASE
                WHEN @partner_id != t.partner_id THEN @rownum := 0
                WHEN @partner_id = t.partner_id THEN @rownum := @rownum + 1
                ELSE @rownum
            END AS weight,
            @partner_id := t.partner_id 
        FROM product t
        JOIN partner p ON t.partner_id = p.id
    ) x
ORDER BY x.weight, x.position)m )g, (SELECT @rank := 0) r;

如果我直接从 MySQL 控制台运行查询,它会起作用:我的结果为

身份证 产品_id partner_id 重量 排名
1 12 3 0 1
2 11 1 0 2
3 13 2 0 3
4 14 3 1 4
5 15 1 1 5

但是如果我使用 Doctrine 和

$this->getEntityManager()->getConnection()->executeStatement

权重和排名始终设置为零。

我哪里做错了?

php mysql doctrine-orm
1个回答
0
投票

您面临的问题可能与 Doctrine 如何处理准备好的语句和 SQL 查询的执行有关。在准备好的语句中,SQL 查询被解析和准备一次,然后绑定参数并使用不同的值多次执行它。但是,在您的情况下,您使用的会话变量(@rank、@partner_id)可以在查询的不同执行之间具有有状态行为。

Doctrine 可能不会像直接在 MySQL 控制台中执行原始 SQL 那样处理会话变量及其状态。要解决此问题,您可以尝试以下几种方法:

1。使用 NativeQuery 执行单语句:

不要使用

executeStatement
,而是尝试使用 Doctrine 的 createNativeQuery 并将整个 SQL 查询作为单个语句执行。这有时可以确保会话变量保持预期的行为。

$sql = "INSERT INTO product_rank (product_id, partner_id, weight, `rank`)
        SELECT g.product_id, g.partner_id, g.weight, g.rank FROM (...your SQL query...)";

$nativeQuery = $this->getEntityManager()->createNativeQuery($sql);
$nativeQuery->getResult();

2。手动重置会话变量:

由于会话变量在原始 SQL 执行和 Doctrine 之间的行为可能有所不同,因此您可以考虑在执行查询之前手动重置会话变量。

$this->getEntityManager()->getConnection()->executeStatement("SET @rank := 0;");
// Now execute your main query
$this->getEntityManager()->getConnection()->executeStatement("...your main SQL query...");

尝试这些方法,看看是否能解决问题。请记住,与直接 SQL 控制台执行相比,Doctrine 在处理 SQL 执行的方式上可能存在一些差异,这些解决方法旨在解决这些差异。

© www.soinside.com 2019 - 2024. All rights reserved.