Почему мой код PHP возвращает неверные результаты запроса MySQL? - PullRequest
0 голосов
/ 13 апреля 2020
  • FreeBSD 11.2-RELEASE
  • Apache 2.4.43
  • PHP 7.4.4
  • MySQL 5.7.29

Приложение, в котором я пишу код (OpensourcePOS), использует платформу CodeIgniter (3.1.11), и я заметил, что она дает неверные результаты запроса с помощью CI QueryBuilder, поэтому я написал запрос в обход CI, но даже тогда результаты не будут правильными.

Этот запрос MySQL выполняется из phpMyAdmin, и CLI возвращает правильные результаты для категории (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', в контексте моего приложения, поэтому я запустил следующий код отладки:

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;
}

Дает мне следующие результаты. Вы можете видеть, что «категория» имеет значение 0. Если идентификатор_поставщика отсутствует (INT (11)), тогда «категория» отображается как ноль.

<code>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'>=&gt;</font> 
    <b>array</b> <i>(size=26)</i>
      ...
      'category' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
      'supplier_id' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
      ...

Если я закомментируйте $this->db->join('suppliers', 'suppliers.person_id = items.supplier_id', 'left'); результат верен, но, конечно, пропущены данные, введенные левым соединением в базе данных поставщиков (что необходимо). Естественно, я думал, что это ошибка CI Querybuilder, поэтому я добавил во второй запрос, чтобы дать мне базовый c выбор всего в таблице элементов, который соответствует моему идентификатору

$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");

, и этот результат правильно, но не дает мне необходимых объединений.

<code>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'>=&gt;</font> 
    <b>array</b> <i>(size=21)</i>
      ...
      'category' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'Books'</font> <i>(length=5)</i>
      'supplier_id' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
      ...

Оттуда я пропустил 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'

<code>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'>=&gt;</font> 
    <b>array</b> <i>(size=28)</i>
      ...
      'category' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
      'supplier_id' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
      ...

Так что я подумал, наверняка это 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 ... те же неверные данные категории:

<code>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'>=&gt;</font> <small>string</small> <font color='#cc0000'>'0'</font> <i>(length=1)</i>
  'supplier_id' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'362'</font> <i>(length=3)</i>
  ...

Кто-нибудь знает, почему работает запрос в phpMyAdmin и CLI, запрос без левого объединения поставщиков работает из моего кода, но добавление в левое объединение не работает в прямом PHP или CI

1 Ответ

1 голос
/ 13 апреля 2020

У вас есть этот запрос:

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 и определите, какие столбцы вы хотите включить.

Что-то вроде: (я не знаю, куда включены ваши категории, но я надеюсь, что вы понимаете концепцию)

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

Затем, когда вы выбираете значения в своем коде, вы получаете категорию 1 (категория товаров) или категорию 2 (категория поставщиков).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...