Codeigniter中的查询生成器会生成正确的SQL语句,但执行查询会导致错误结果

问题描述:

我正在使用Codeigniter查询生成器来生成我的SQL查询。在通过$this->db->get()运行查询时,结果由PK列中的空值组成,这是不正确的(证据在下面提供)。Codeigniter中的查询生成器会生成正确的SQL语句,但执行查询会导致错误结果

查看生成的SQL查询,通过$this->db->get_compiled_select(),SQL查询被确认为正确创建。此外,我以两种不同的方式测试SQL查询:

  1. 通过直接在MySQL上执行。获得的结果是正确的,并且在任何PK列中都不包含空值。
  2. 再次运行Codeigniter,但这次使用$this->db->query('SQL query string')。同样,得到的结果是正确的,并且在任何PK列中都不包含空值。

除此之外,我通过打开通用查询日志来记录发送到MySQL的查询,如this resource中所述。在所有3种情况下(即通过查询构建器类运行查询,通过MySQL命令行直接运行查询以及通过codeigniter运行查询,但使用$ this-> db-> query()),MySQL收到的SQL查询是一样。

鉴于上述证据,我是否正确地得出这是Codeigniter Query Builder Class中的错误的结论?或者我错过了一些其他的错误来源?

下面给出的是我的表内容,和源代码:

餐厅表:

RestaurantID Name 
1    Awesome Bar 
2    Disco Deewaane 
3    Decibel Disco 
4    Basswaala Bar 

出口表(列RestaurantID是FK餐厅页表):

OutletID RestaurantID Name    Address   Phone     Latitude Longitude 
1  1 [->]  Awesome Bar  Roop Nagar  9837464231    0  0 
2  1 [->]  Aww Bar   Prem Bhavan  8461232871    0  0 
3  2 [->]  Disco Deewaane Gali Number 420 8372313874    0  0 
4  2 [->]  Decibel Disc  Excuse Me Please 9833346521    0  0 
5  3 [->]  Disc Dec   Roop Nagar  8375643111    0  0 
6  4 [->]  Bass Down Low Prem Bhavan  9988843511    0  0 
7  4 [->]  Baby ka Bass Bar Gali Number 420 8883741234    0  0 
8  4 [->]  Basswaala Bar Excuse Me Please 9993741236,8843621439 0  0 

OutletTable表(OutletID是FK to出口表):

TableID OutletID TableNumber Capacity Smoking Available  
1  1 [->] 1   6  0  1 
2  1 [->] 2   6  0  1 
3  1 [->] 3   8  1  1 
4  2 [->] 1   4  1  1 
5  2 [->] 2   4  1  1 
6  2 [->] 3   6  1  1 
7  3 [->] 1   6  1  1 
8  3 [->] 2   6  1  1 
9  3 [->] 3   4  1  1 
10  3 [->] 4   5  1  1 
11  1 [->] z   10  1  0 

查询的问题:从查询

SELECT * 
FROM `Restaurant` 
RIGHT JOIN `Outlet` ON `Restaurant`.`RestaurantID` = `Outlet`.`RestaurantID` 
LEFT JOIN `OutletTable` ON `Outlet`.`OutletID` = `OutletTable`.`OutletID` 

正确的结果:

enter image description here

结果实际使用查询生成器CLA时获得SS

注意从指数11日起,则OutletID不正确报告并获得空(这就是为什么它显示在下面的print_r输出为空白):

Array 
(
    [0] => stdClass Object 
     (
      [RestaurantID] => 1 
      [Name] => Awesome Bar 
      [OutletID] => 1 
      [Address] => Roop Nagar 
      [Phone] => 9837464231 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 1 
      [TableNumber] => 1 
      [Capacity] => 6 
      [Smoking] => 0 
      [Available] => 1 
     ) 

    [1] => stdClass Object 
     (
      [RestaurantID] => 1 
      [Name] => Awesome Bar 
      [OutletID] => 1 
      [Address] => Roop Nagar 
      [Phone] => 9837464231 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 2 
      [TableNumber] => 2 
      [Capacity] => 6 
      [Smoking] => 0 
      [Available] => 1 
     ) 

    [2] => stdClass Object 
     (
      [RestaurantID] => 1 
      [Name] => Awesome Bar 
      [OutletID] => 1 
      [Address] => Roop Nagar 
      [Phone] => 9837464231 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 3 
      [TableNumber] => 3 
      [Capacity] => 8 
      [Smoking] => 1 
      [Available] => 1 
     ) 

    [3] => stdClass Object 
     (
      [RestaurantID] => 1 
      [Name] => Awesome Bar 
      [OutletID] => 1 
      [Address] => Roop Nagar 
      [Phone] => 9837464231 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 11 
      [TableNumber] => z 
      [Capacity] => 10 
      [Smoking] => 1 
      [Available] => 0 
     ) 

    [4] => stdClass Object 
     (
      [RestaurantID] => 1 
      [Name] => Aww Bar 
      [OutletID] => 2 
      [Address] => Prem Bhavan 
      [Phone] => 8461232871 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 4 
      [TableNumber] => 1 
      [Capacity] => 4 
      [Smoking] => 1 
      [Available] => 1 
     ) 

    [5] => stdClass Object 
     (
      [RestaurantID] => 1 
      [Name] => Aww Bar 
      [OutletID] => 2 
      [Address] => Prem Bhavan 
      [Phone] => 8461232871 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 5 
      [TableNumber] => 2 
      [Capacity] => 4 
      [Smoking] => 1 
      [Available] => 1 
     ) 

    [6] => stdClass Object 
     (
      [RestaurantID] => 1 
      [Name] => Aww Bar 
      [OutletID] => 2 
      [Address] => Prem Bhavan 
      [Phone] => 8461232871 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 6 
      [TableNumber] => 3 
      [Capacity] => 6 
      [Smoking] => 1 
      [Available] => 1 
     ) 

    [7] => stdClass Object 
     (
      [RestaurantID] => 2 
      [Name] => Disco Deewaane 
      [OutletID] => 3 
      [Address] => Gali Number 420 
      [Phone] => 8372313874 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 7 
      [TableNumber] => 1 
      [Capacity] => 6 
      [Smoking] => 1 
      [Available] => 1 
     ) 

    [8] => stdClass Object 
     (
      [RestaurantID] => 2 
      [Name] => Disco Deewaane 
      [OutletID] => 3 
      [Address] => Gali Number 420 
      [Phone] => 8372313874 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 8 
      [TableNumber] => 2 
      [Capacity] => 6 
      [Smoking] => 1 
      [Available] => 1 
     ) 

    [9] => stdClass Object 
     (
      [RestaurantID] => 2 
      [Name] => Disco Deewaane 
      [OutletID] => 3 
      [Address] => Gali Number 420 
      [Phone] => 8372313874 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 9 
      [TableNumber] => 3 
      [Capacity] => 4 
      [Smoking] => 1 
      [Available] => 1 
     ) 

    [10] => stdClass Object 
     (
      [RestaurantID] => 2 
      [Name] => Disco Deewaane 
      [OutletID] => 3 
      [Address] => Gali Number 420 
      [Phone] => 8372313874 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 10 
      [TableNumber] => 4 
      [Capacity] => 5 
      [Smoking] => 1 
      [Available] => 1 
     ) 

    [11] => stdClass Object 
     (
      [RestaurantID] => 2 
      [Name] => Decibel Disc 
      [OutletID] => 
      [Address] => Excuse Me Please 
      [Phone] => 9833346521 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 
      [TableNumber] => 
      [Capacity] => 
      [Smoking] => 
      [Available] => 
     ) 

    [12] => stdClass Object 
     (
      [RestaurantID] => 3 
      [Name] => Disc Dec 
      [OutletID] => 
      [Address] => Roop Nagar 
      [Phone] => 8375643111 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 
      [TableNumber] => 
      [Capacity] => 
      [Smoking] => 
      [Available] => 
     ) 

    [13] => stdClass Object 
     (
      [RestaurantID] => 4 
      [Name] => Bass Down Low 
      [OutletID] => 
      [Address] => Prem Bhavan 
      [Phone] => 9988843511 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 
      [TableNumber] => 
      [Capacity] => 
      [Smoking] => 
      [Available] => 
     ) 

    [14] => stdClass Object 
     (
      [RestaurantID] => 4 
      [Name] => Baby ka Bass Bar 
      [OutletID] => 
      [Address] => Gali Number 420 
      [Phone] => 8883741234 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 
      [TableNumber] => 
      [Capacity] => 
      [Smoking] => 
      [Available] => 
     ) 

    [15] => stdClass Object 
     (
      [RestaurantID] => 4 
      [Name] => Basswaala Bar 
      [OutletID] => 
      [Address] => Excuse Me Please 
      [Phone] => 9993741236,8843621439 
      [Latitude] => 0 
      [Longitude] => 0 
      [TableID] => 
      [TableNumber] => 
      [Capacity] => 
      [Smoking] => 
      [Available] => 
     ) 

) 
+1

对不起!查询是正确的但会产生不正确的结果_不计算!逻辑炸弹种植_ – RiggsFolly

+0

你能告诉我们你说这个数组是否是错误的请创建。这可能相当相关 – RiggsFolly

+1

这是否证明矩阵是真实的? 尽管如此,我对如何调试这一点感到茫然。在$ this-> db-> query()中使用时,从$ this-> db-> get_compiled_select()获取的查询会生成与$ this-> db-> get()不同的结果! – Chaos

你在截图中可以看到有两个OutletID列,其中之一是从第11个结果开始的NULL

我的猜测是,由于CI中的结果是一个关联数组,所以存储了OutletID(本例中为NULL)的最后一次发生。

我建议不使用SELECT *但沿着线的东西:

SELECT Restaurant.RestaurantID AS "RestaurantID", [...], 
     Outlet.OutletID AS "OutletID", [...], 
     OutletTable.OutletID AS "OutletID2", [...] 
+0

Oooo漂亮的渔获 – RiggsFolly

+0

你是The Chosen One!获得的经验 - 错误越令人沮丧,它就越容易成为我忽略的世俗问题,而不是框架中的善意错误。谢谢! – Chaos

+1

不客气。请记住,尽管看起来更容易,但在带有JOIN的查询中使用SELECT *几乎不是一种好的做法,如果单独表中的某些列具有相同的名称,那么这会非常显着。我总是试着添加一个与每个列的表名相对应的后缀,如你的案例中的'OutletID_outlet'和'OutletID_outletTable';) – roberto06