php - MySQL 存储过程没有返回插入 ID?

标签 php mysql codeigniter

我有一个非常简单的查询,不确定我在这里做错了什么。

我的数据库调用没有收到我期望的 insert id

表格:

enter image description here

存储过程:

CREATE DEFINER=`root`@`localhost` PROCEDURE `addCustomerProduct`(IN in_customerID INT, in_productID INT)
BEGIN
    INSERT INTO order_customer_product (customerID, productID, retailAmountAtPurchase, faceValue)
    SELECT
        in_customerID,
        in_productID,
        p.retail,
        p.faceValue
    FROM
        products as p
    WHERE 
        p.productID = in_productID;
END

PHP:

   public function addProduct($data, $userID)
    {
        // Do we already have a pending order for this user?
        $orderID = $this->doesOrderExist($userID);

        // We had no order, lets create one
        if (!$orderID) {
            $orderID = $this->createOrder($userID);
        }

        /**
         * Insert the customer product.
         * This relates a denomination to a customer.
         */
        $customerProductID = $this->addCustomerProduct($data);

        // Add this customer product to the order
        $this->addProductToOrder(array("customerProductID" => $customerProductID, "orderID" => $orderID));

        // Return
        return $customerProductID;
    }

    /**
     * Description: Add a customer product / reward
     * Page: client/add_reward
     */
    public function addCustomerProduct($data){
        $procedure = "CALL addCustomerProduct(?,?)";
        $result = $this->db->query($procedure, $data);
        return $this->db->insert_id();
    }

有问题的行是:$customerProductID = $this->addCustomerProduct($data);

正在向表中插入一条新记录,并且该表有一个 PK/AI。数据正常,但 0 作为 $customerProductID 返回。

从 select 语句插入可能不会返回 insert ID 吗?

更新@Ravi-

enter image description here

更新 2:

我创建了一个单独的方法并对要发送的查询和数据进行硬编码。

它很好地添加了记录,AI 上升,0 作为 last id 返回。

public function test(){
    $procedure = "CALL addCustomerProduct(?,?)";
    $result = $this->db->query($procedure, array("customerID" => 1, "productID" => 20));
    echo $this->db->insert_id();
}

还重新启动了 MySQL 服务器以确保那里没有发生任何奇怪的事情。

此外,更新了 SP 以在不使用选择的情况下将随机数据插入表中。

CREATE DEFINER=`root`@`localhost` PROCEDURE `addCustomerProduct`(IN in_customerID INT, in_productID INT)
BEGIN
    INSERT INTO order_customer_product (customerID, productID, retailAmountAtPurchase, faceValue)
    VALUES(8,2,'4.55',25);
END

更新 3:

插入后,我将打印出最后运行的查询以及结果。您会注意到有 1 个受影响的行(正在插入),但 insert_id 仍为 0。

CALL addCustomerProduct('8','33')

CI_DB_mysqli_result Object
(
    [conn_id] => mysqli Object
        (
            [affected_rows] => 1
            [client_info] => mysqlnd 5.0.12-dev - 20150407 - $Id: b396954eeb2d1d9ed7902b8bae237b287f21ad9e $
            [client_version] => 50012
            [connect_errno] => 0
            [connect_error] => 
            [errno] => 0
            [error] => 
            [error_list] => Array
                (
                )

            [field_count] => 0
            [host_info] => Localhost via UNIX socket
            [info] => 
            [insert_id] => 0
            [server_info] => 5.6.35
            [server_version] => 50635
            [stat] => Uptime: 1637  Threads: 3  Questions: 508  Slow queries: 0  Opens: 113  Flush tables: 1  Open tables: 106  Queries per second avg: 0.310
            [sqlstate] => 00000
            [protocol_version] => 10
            [thread_id] => 25
            [warning_count] => 0
        )

    [result_id] => 1
    [result_array] => Array
        (
        )

    [result_object] => Array
        (
        )

    [custom_result_object] => Array
        (
        )

    [current_row] => 0
    [num_rows] => 
    [row_data] => 
)

更新 4:

根据我所做的一些研究,除非您使用 mysqli 方法,例如 $this->db->insert(),否则它不会向您提供最后的插入 ID .

我将尝试找出 Ravi 的建议,但代码点火器似乎不允许显示的示例。至少我现在知道我并不疯狂,这只是不正常的行为,除非你使用 ``insert` 方法而不是存储过程。

最佳答案

This answer可能会解释为什么您现有的代码不起作用。引用:

CodeIgniter's insert_id() will only return an ID of an insert(). Unless you are executing something like $this->db->insert('table', $data); before calling the function it will not be able to return an ID.

MySQL 的 LAST_INSERT_ID();应该在这里帮助你(假设你有权改变存储过程定义)。将其更改为:

CREATE DEFINER=`root`@`localhost` PROCEDURE `addCustomerProduct`(
    IN in_customerID INT, in_productID INT, OUT out_customerProductID INT)
BEGIN
    INSERT INTO order_customer_product (
        customerID, productID, retailAmountAtPurchase, faceValue)
    VALUES(8,2,'4.55',25);

    SELECT LAST_INSERT_ID() INTO out_customerProductID;
END

然后使用类似下面的方法获取输出参数值:

public function addCustomerProduct($data) {
    $procedure = "CALL addCustomerProduct("
                   . $this->db->escape($data["customerID"]).", "
                   . $this->db->escape($data["productID"]).", "
                   . "@customerProductID);"
    $this->db->query($procedure);
    $query = $this->db->query("SELECT @customerProductID AS customerProductID");
    if($query->num_rows() > 0)
      return $query->result()->customerProductID;
    else
      return NULL;
}

如果上述方法不起作用,请尝试添加 $this->db->trans_start();$this->db->trans_complete(); 在存储过程调用之前和之后确保事务已提交。

关于php - MySQL 存储过程没有返回插入 ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48247398/

相关文章:

mysql - Moodle SQL - 使用 2 个用户配置文件字段数据创建过滤器

mysql - 添加 2 个文本框的值以在其中之一中显示结果

php - Bootstrap jumbotron 自动根据内容量改变大小

codeigniter - Codeigniter 3 中使用不同数据库的表单验证

sql - 社交网络查询之间的区别

php - 如何将模型存储在文件夹中

php - 这个简单的反垃圾邮件概念有效吗? (需要优化吗?)

php - Laravel 中如何获取当前查询的 DB_HOST 值

PHP Redis 错误 : Uncaught exception ‘RedisException’

php - 将 mysql 数据导入表,编辑/克隆行,并插入新行