phpmysqlcodeignitersql-updatesubquery

MySQL UPDATE with comma-JOIN on subquery in CodeIgniter


For the query below the MySQL terminal and MySQL Workbench give the same result, but PHP gives a different result.

I want to decrease one item from quantity. But in PHP (Codeigniter with a PDO connection) it subtracts two items from quantity.

I'm not executing this query twice (in a loop).

UPDATE tbl_stock tsk,
    (SELECT 
        tsk.id_stock, tsk.qty
    FROM
        tbl_store ts
    inner join tbl_stock tsk ON ts.id_store = tsk.id_store
    where
        ts.id_physical_place = 2
            and ts.store_status = 1
            and tsk.stock_status = 1
            and tsk.id_products = 796
    limit 1) tmp 
SET 
    tsk.qty = (if(tmp.qty >= 1,
        (tmp.qty - 1),
        ifnull(tmp.qty, 0)))
WHERE
    tsk.id_stock = tmp.id_stock

From the terminal:

Query OK, 1 row affected, 2 warnings (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0

Note (Code 1592): Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted. Note (Code 1592): Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statements writing to a table with an auto-increment column after selecting from another table are unsafe because the order in which rows are retrieved determines what (if any) rows will be written. This order cannot be predicted and may differ on master and the slave.


Solution

  • Execute them separately:

    $mod_select = $this->db->mod_select("
       SELECT
           tsk.id_stock, tsk.qty
       FROM
           tbl_store ts
       inner join tbl_stock tsk ON ts.id_store = tsk.id_store
       where
           ts.id_physical_place = " . $all_userdata['id_physical_place'] . "
               and ts.store_status = 1
               and tsk.stock_status = 1
               and tsk.id_products = " . $value['itm'] . " limit 1");
    if ($mod_select[0]->qty >= $value['qty']) {
        $this->db->update('tbl_stock', array('qty' => $mod_select[0]->qty - $value['qty']), array('id_stock' => $mod_select[0]->id_stock));
    }