【问题标题】:ZF2 how to avoid sql query limit to add quotes in subqueryZF2如何避免sql查询限制在子查询中添加引号
【发布时间】:2014-07-16 15:45:06
【问题描述】:

我正在尝试在 ZendFramework 2 中设置子查询,但遇到了 Select 对象的限制函数问题。无论我做什么,数值都会放在引号之间,使我的查询失败:我应该得到 LIMIT 1 而我得到 LIMIT '1'。

似乎这不是第一次遇到这个问题,我看到一些人之前(比如 8 个月前)问过这个问题,但没有得到任何正确的答案。 我还看到这个问题已在 2012 年被标记为已解决 (https://github.com/zendframework/zf2/pull/2775),所以我真的不明白那里发生了什么。

这是我在 ZF2 中的代码:

$resultSet = $this->tableGateway->select( function (Select $select) use ($params)   {
        $sub = new Select();
        $sub->from(array('temp' => 'scores'))
            ->columns(array(new \Zend\Db\Sql\Expression("id AS id")))
            ->where(array('temp.glitch' => array('None', 'Glitch')))
            ->where('temp.zone=scores.zone')
            ->order('temp.multi DESC, temp.score DESC')
            ->limit(1);

        $select->join('players', 'player=players.id', array('player_name' => 'name', 'player_url' => 'name_url'))
            ->join('countries', 'players.country=countries.id', array('country_name' => 'name', 'country_iso' => 'iso'))
            ->join('cars', 'car=cars.id', array('car_name' => 'name'), 'left')
            ->join('zones', 'zone=zones.id', array('zone_name' => 'name'));
        $select->where(array('scores.id' => $sub));
        $select->order('scores.zone ASC');
        print_r($select->getSqlString());
    });

这应该呈现以下查询(除了 LIMIT '1' 而不是 LIMIT 1,我得到了正确的查询):

SELECT "scores".*, "players"."name" AS "player_name", "players"."name_url" AS "player_url", "countries"."name" AS "country_name", "countries"."iso" AS "country_iso", "cars"."name" AS "car_name", "zones"."name" AS "zone_name" 
FROM "scores" INNER JOIN "players" ON "player"="players"."id" 
INNER JOIN "countries" ON "players"."country"="countries"."id" 
LEFT JOIN "cars" ON "car"="cars"."id" 
INNER JOIN "zones" ON "zone"="zones"."id"
WHERE "scores"."id" = (SELECT id AS id FROM "scores" AS "temp" WHERE "temp"."glitch" IN ('None', 'Glitch') 
AND temp.zone=scores.zone ORDER BY "temp"."multi" DESC, "temp"."score" DESC LIMIT 1)     
ORDER BY "scores"."zone" ASC

由于这似乎不起作用,是否有另一种方法可以继续获得我的限制(使用 Mysql 5 数据库)?

编辑: 谢谢你的帮助。最后我想出了一种方法来按照我想要的方式完成工作,并通过简单地删除子查询结构并将其直接写入 where 函数来删除引号:

$select->where('scores.id = (SELECT id FROM scores AS lookup WHERE lookup.zone = scores.zone ORDER BY multi DESC , score DESC LIMIT 1)');

虽然我可以继续我的开发,但我更喜欢使用一个糟糕的技巧来摆脱这个问题,所以我会让这个问题无人回答,直到有人在那里提出真正的解决方案。 无论如何,可能根本没有解决方案,因为这可能是 ZF2 内核本身的问题。

【问题讨论】:

  • 我认为您必须在 limit 中使用变量而不是常量 1。如果是,那么只需将整数转换为变量。
  • 我尝试使用 1、'1'、"1" 和一个变量(有和没有演员表),但它给出了相同的结果,并且在最终查询中有引号:/

标签: sql zend-framework2 subquery limit quotes


【解决方案1】:

换行-

$select->where(array('scores.id' => $sub));

$select->where(array('scores.id' => new \Zend\Db\Sql\Expression("({$sub->getSqlString($this->tableGateway->adapter->getPlatform())})"));

尝试上述更改。

如果它仍然不起作用,则更改位于 - 的核心 Select 类文件 -

PROJECT_FOLDER/vendor/zendframework/zendframework/library/Zend/Db/Sql/Select.php

  1. 第 921 行 - 将$sql = $platform->quoteValue($limit); 更改为$sql = $limit;

  2. 第 940 行 - 将return array($platform->quoteValue($offset)); 更改为return array($offset);

我从 github 遇到了这个问题,想知道为什么它仍然无法使用最新的 ZF2 文件。我知道上面给出的解决方案看起来不合适,但我必须以某种方式使它起作用。我试过了,效果很好。

这只是在实际解决方案出现之前的快速修复。

【讨论】:

  • 没想到这个,试过了,可惜没用,还是得到这个引用。
  • 尝试对上述答案的新更改。上一个答案需要对核心 Select 类文件进行一些更改。那是我遇到与您相同的情况时所做的事情。希望新答案对您有所帮助。
  • 确实,我尝试了您在核心 Select 中进行更改的解决方案,并且成功了。我可能看起来没有冒险精神,但是因为我可以摆脱子查询(就像我昨天的编辑一样)我宁愿不更改核心 Select 以避免不必要的后果......所以我只检查了你的解决方案,但会保留硬代码最后查询。无论如何,非常感谢您的帮助,我在这里了解了一些东西,您的解决方案可能会帮助一些需要修复的人,直到 ZF2 出现官方解决方案。
  • 嗨@KunalDethe,问候!我按照您的指示更改了核心文件,但是当我执行如下查询时,查询仍然无法按预期工作。极限值被忽略! $statement = $this->sql->prepareStatementForSqlObject($select);$dataSource = $statement->execute();是不是我在执行语句的时候做错了什么?
猜你喜欢
  • 1970-01-01
  • 2016-06-28
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 2017-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多