为什么我的 PHP 代码从 MySQL 查询返回不正确的结果?
Why is my PHP code returning incorrect results from a MySQL query?
- FreeBSD 11.2-RELEASE
- 阿帕奇 2.4.43
- PHP7.4.4
- MySQL 5.7.29
我在 (OpensourcePOS) 中编写代码的应用程序使用 CodeIgniter 框架 (3.1.11),我注意到它使用 CI QueryBuilder 给我不正确的查询结果,所以我手写了查询绕过CI 完全一样,但即便如此,结果也不正确。
来自 phpMyAdmin 的 MySQL 查询 运行 和 CLI returns 'category' (VARCHAR(255))
的正确结果
SELECT * FROM ospos_items items
LEFT JOIN ospos_suppliers suppliers
ON suppliers.person_id = items.supplier_id
JOIN ospos_item_quantities qty
ON qty.item_id = items.item_id
WHERE items.deleted = 0
ORDER BY items.name ASC
LIMIT 1 OFFSET 0
字段 'category' 被报告为 'Books',就像它应该的那样。问题是,在我的应用程序上下文中,我没有看到我期望的 'Category' 数据,所以我 运行 以下调试代码:
public function get_all($stock_location_id = -1, $rows = 0, $limit_from = 0)
{
$this->db->from('items');
$this->db->join('suppliers', 'suppliers.person_id = items.supplier_id', 'left');
if($stock_location_id > -1)
{
$this->db->join('item_quantities', 'item_quantities.item_id = items.item_id');
$this->db->where('location_id', $stock_location_id);
}
$this->db->where('items.deleted', 0);
$this->db->order_by('items.name', 'asc');
if($rows > 0)
{
$this->db->limit($rows, $limit_from);
}
$result_items = $this->db->get();
//DEBUG CODE
ob_start();
var_dump($result_items->result_array());
$res = ob_get_clean();
log_message('Error',"get_all results: $res");
//END DEBUG CODE
return $result_items;
}
给我以下结果。您可以看到 'category' 的值为 0。如果没有 supplier_id (INT(11)),则 'category' 显示为 null。
ERROR - 2020-04-10 16:21:34 --> get_all results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:278:</small>
<b>array</b> <i>(size=1)</i>
0 <font color='#888a85'>=></font>
<b>array</b> <i>(size=26)</i>
...
'category' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
'supplier_id' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
...
</pre>
如果我注释掉 $this->db->join('suppliers', 'suppliers.person_id = items.supplier_id', 'left');
结果是正确的,但当然缺少供应商数据库中左连接带来的数据(这是必需的)。所以很自然地,我认为这是一个 CI Querybuilder 错误,所以我在第二个查询中添加了一个基本的 select 项目 table 中与我的 ID [=22= 匹配的所有内容]
$query = $this->db->get_where('items',array('item_id'=>12203));
ob_start();
var_dump($query->result_array());
$res2 = ob_get_clean();
log_message('Error',"Custom query results: $res2");
结果是正确的,但没有提供我需要的联接。
ERROR - 2020-04-10 16:21:34 --> Custom query results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:284:</small>
<b>array</b> <i>(size=1)</i>
0 <font color='#888a85'>=></font>
<b>array</b> <i>(size=21)</i>
...
'category' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'Books'</font> <i>(length=5)</i>
'supplier_id' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
...
</pre>
从那里我跳过 CI QueryBuilder 并写出查询,但仍然使用 CI 框架来处理连接。
$query2 = $this->db->query("SELECT * FROM `ospos_items` items LEFT JOIN `ospos_suppliers` suppliers ON suppliers.person_id = items.supplier_id JOIN ospos_item_quantities qty ON qty.item_id = items.item_id WHERE items.deleted = 0 ORDER BY items.name ASC LIMIT 1 OFFSET 0");
ob_start();
var_dump($query2->result_array());
$res3 = ob_get_clean();
log_message('Error',"HANDWRITTEN query results: $res3");
... 我得到了 'category'
相同的错误数据
ERROR - 2020-04-10 16:21:34 --> HANDWRITTEN query results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:290:</small>
<b>array</b> <i>(size=1)</i>
0 <font color='#888a85'>=></font>
<b>array</b> <i>(size=28)</i>
...
'category' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
'supplier_id' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
...
</pre>
所以我想,这肯定是一个 CI 错误!我完全绕过了 CI 框架并手动编写了查询,使用 PHP 来处理所有事情
$username = "[REDACTED]";
$password = "[REDACTED]";
$database = "[REDACTED]";
$mysqli = new mysqli("localhost", $username, $password, $database);
$query3="SELECT * FROM `ospos_items` items LEFT JOIN `ospos_suppliers` suppliers ON suppliers.person_id = items.supplier_id JOIN ospos_item_quantities qty ON qty.item_id = items.item_id WHERE items.deleted = 0 ORDER BY items.name ASC LIMIT 1 OFFSET 0";
$result3 = $mysqli->query("$query3");
$mysqli->close();
ob_start();
var_dump($result3->fetch_assoc());
$res4 = ob_get_clean();
log_message('Error',"noCI query results: $res4");
annnndd...同样不正确 'category' 数据:
ERROR - 2020-04-10 16:21:34 --> noCI query results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:302:</small>
<b>array</b> <i>(size=28)</i>
...
'category' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
'supplier_id' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
...
</pre>
有没有人知道为什么 phpMyAdmin 和 CLI 中的查询有效,供应商没有左连接的查询在我的代码中有效,但添加左连接在直接 PHP 中不起作用CI?
您有这个查询:
SELECT * FROM ospos_items items
LEFT JOIN ospos_suppliers suppliers
ON suppliers.person_id = items.supplier_id
JOIN ospos_item_quantities qty
ON qty.item_id = items.item_id
WHERE items.deleted = 0
ORDER BY items.name ASC
LIMIT 1 OFFSET 0
根据您的评论,您在 PHPMyAdmin 中检索到具有类别的两列:
您应该在 SQL 中使用 aliases,而不是使用 * 并定义您想要包含的列。
类似于:(我不知道您的类别包含在哪里,但我希望您理解这个概念)
SELECT items.category as category1, suppliers.category as category2, {other columns}
FROM ospos_items items
LEFT JOIN ospos_suppliers suppliers
ON suppliers.person_id = items.supplier_id
JOIN ospos_item_quantities qty
ON qty.item_id = items.item_id
WHERE items.deleted = 0
ORDER BY items.name ASC
LIMIT 1 OFFSET 0
然后当您在代码中获取值时,您会得到 category1(商品类别)或 category2(供应商类别)。
- FreeBSD 11.2-RELEASE
- 阿帕奇 2.4.43
- PHP7.4.4
- MySQL 5.7.29
我在 (OpensourcePOS) 中编写代码的应用程序使用 CodeIgniter 框架 (3.1.11),我注意到它使用 CI QueryBuilder 给我不正确的查询结果,所以我手写了查询绕过CI 完全一样,但即便如此,结果也不正确。
来自 phpMyAdmin 的 MySQL 查询 运行 和 CLI returns 'category' (VARCHAR(255))
的正确结果SELECT * FROM ospos_items items
LEFT JOIN ospos_suppliers suppliers
ON suppliers.person_id = items.supplier_id
JOIN ospos_item_quantities qty
ON qty.item_id = items.item_id
WHERE items.deleted = 0
ORDER BY items.name ASC
LIMIT 1 OFFSET 0
字段 'category' 被报告为 'Books',就像它应该的那样。问题是,在我的应用程序上下文中,我没有看到我期望的 'Category' 数据,所以我 运行 以下调试代码:
public function get_all($stock_location_id = -1, $rows = 0, $limit_from = 0)
{
$this->db->from('items');
$this->db->join('suppliers', 'suppliers.person_id = items.supplier_id', 'left');
if($stock_location_id > -1)
{
$this->db->join('item_quantities', 'item_quantities.item_id = items.item_id');
$this->db->where('location_id', $stock_location_id);
}
$this->db->where('items.deleted', 0);
$this->db->order_by('items.name', 'asc');
if($rows > 0)
{
$this->db->limit($rows, $limit_from);
}
$result_items = $this->db->get();
//DEBUG CODE
ob_start();
var_dump($result_items->result_array());
$res = ob_get_clean();
log_message('Error',"get_all results: $res");
//END DEBUG CODE
return $result_items;
}
给我以下结果。您可以看到 'category' 的值为 0。如果没有 supplier_id (INT(11)),则 'category' 显示为 null。
ERROR - 2020-04-10 16:21:34 --> get_all results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:278:</small>
<b>array</b> <i>(size=1)</i>
0 <font color='#888a85'>=></font>
<b>array</b> <i>(size=26)</i>
...
'category' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
'supplier_id' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
...
</pre>
如果我注释掉 $this->db->join('suppliers', 'suppliers.person_id = items.supplier_id', 'left');
结果是正确的,但当然缺少供应商数据库中左连接带来的数据(这是必需的)。所以很自然地,我认为这是一个 CI Querybuilder 错误,所以我在第二个查询中添加了一个基本的 select 项目 table 中与我的 ID [=22= 匹配的所有内容]
$query = $this->db->get_where('items',array('item_id'=>12203));
ob_start();
var_dump($query->result_array());
$res2 = ob_get_clean();
log_message('Error',"Custom query results: $res2");
结果是正确的,但没有提供我需要的联接。
ERROR - 2020-04-10 16:21:34 --> Custom query results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:284:</small>
<b>array</b> <i>(size=1)</i>
0 <font color='#888a85'>=></font>
<b>array</b> <i>(size=21)</i>
...
'category' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'Books'</font> <i>(length=5)</i>
'supplier_id' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
...
</pre>
从那里我跳过 CI QueryBuilder 并写出查询,但仍然使用 CI 框架来处理连接。
$query2 = $this->db->query("SELECT * FROM `ospos_items` items LEFT JOIN `ospos_suppliers` suppliers ON suppliers.person_id = items.supplier_id JOIN ospos_item_quantities qty ON qty.item_id = items.item_id WHERE items.deleted = 0 ORDER BY items.name ASC LIMIT 1 OFFSET 0");
ob_start();
var_dump($query2->result_array());
$res3 = ob_get_clean();
log_message('Error',"HANDWRITTEN query results: $res3");
... 我得到了 'category'
相同的错误数据ERROR - 2020-04-10 16:21:34 --> HANDWRITTEN query results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:290:</small>
<b>array</b> <i>(size=1)</i>
0 <font color='#888a85'>=></font>
<b>array</b> <i>(size=28)</i>
...
'category' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
'supplier_id' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
...
</pre>
所以我想,这肯定是一个 CI 错误!我完全绕过了 CI 框架并手动编写了查询,使用 PHP 来处理所有事情
$username = "[REDACTED]";
$password = "[REDACTED]";
$database = "[REDACTED]";
$mysqli = new mysqli("localhost", $username, $password, $database);
$query3="SELECT * FROM `ospos_items` items LEFT JOIN `ospos_suppliers` suppliers ON suppliers.person_id = items.supplier_id JOIN ospos_item_quantities qty ON qty.item_id = items.item_id WHERE items.deleted = 0 ORDER BY items.name ASC LIMIT 1 OFFSET 0";
$result3 = $mysqli->query("$query3");
$mysqli->close();
ob_start();
var_dump($result3->fetch_assoc());
$res4 = ob_get_clean();
log_message('Error',"noCI query results: $res4");
annnndd...同样不正确 'category' 数据:
ERROR - 2020-04-10 16:21:34 --> noCI query results: <pre class='xdebug-var-dump' dir='ltr'>
<small>/usr/local/www/public_html/pos_clcdesq/application/models/Item.php:302:</small>
<b>array</b> <i>(size=28)</i>
...
'category' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
'supplier_id' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
...
</pre>
有没有人知道为什么 phpMyAdmin 和 CLI 中的查询有效,供应商没有左连接的查询在我的代码中有效,但添加左连接在直接 PHP 中不起作用CI?
您有这个查询:
SELECT * FROM ospos_items items
LEFT JOIN ospos_suppliers suppliers
ON suppliers.person_id = items.supplier_id
JOIN ospos_item_quantities qty
ON qty.item_id = items.item_id
WHERE items.deleted = 0
ORDER BY items.name ASC
LIMIT 1 OFFSET 0
根据您的评论,您在 PHPMyAdmin 中检索到具有类别的两列:
您应该在 SQL 中使用 aliases,而不是使用 * 并定义您想要包含的列。
类似于:(我不知道您的类别包含在哪里,但我希望您理解这个概念)
SELECT items.category as category1, suppliers.category as category2, {other columns}
FROM ospos_items items
LEFT JOIN ospos_suppliers suppliers
ON suppliers.person_id = items.supplier_id
JOIN ospos_item_quantities qty
ON qty.item_id = items.item_id
WHERE items.deleted = 0
ORDER BY items.name ASC
LIMIT 1 OFFSET 0
然后当您在代码中获取值时,您会得到 category1(商品类别)或 category2(供应商类别)。