Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php PDO lastInsertID()由于在一次调用中运行多个查询而失败_Php_Mysql_Pdo - Fatal编程技术网

Php PDO lastInsertID()由于在一次调用中运行多个查询而失败

Php PDO lastInsertID()由于在一次调用中运行多个查询而失败,php,mysql,pdo,Php,Mysql,Pdo,这很奇怪。我运行的查询只有一个INSERT,前面有一个SET语句。查询如下所示: SET @discount:=(SELECT discount * :applyDiscount FROM fra_cus WHERE customerID=:customerID AND franchiseID=:franchiseID); INSERT INTO discounts_applied (unitID, franchiseID, customerID, amount) VALUES(:un

这很奇怪。我运行的查询只有一个INSERT,前面有一个SET语句。查询如下所示:

SET @discount:=(SELECT discount * :applyDiscount FROM fra_cus WHERE customerID=:customerID AND franchiseID=:franchiseID);

INSERT INTO discounts_applied (unitID, franchiseID, customerID, amount)
    VALUES(:unitID, :franchiseID, :customerID, @discount * :price);
看起来,如果我将它们作为两个单独的PDO查询准备,lastInsertID()就可以正常工作了。。。但是如果我准备它们并在同一语句中执行它们,lastInsertID()将不返回任何结果


这不是世界末日,但很烦人。有人知道为什么会这样吗?作为记录,我需要将@折扣定义为一个变量(与其中一个表上的触发器有关)。而且这一切都发生在一个更大的事务中。

首先,我强烈建议在一个不同的API调用中运行每个查询。这就是应用程序编程接口的工作方式

它不仅可以防止出现这种情况,还可以使代码的可读性和可维护性大大提高

这也会使您的代码更加安全。您只能在一次调用中运行多个语句,而代价是本机准备的语句。不管这个漏洞多么虚拟,为什么要冒险呢

为什么不做一个常规的SELECT查询而不是SET,将结果值放入一个PHP变量中,然后通过占位符在其他变量中使用它呢?我看不出有什么理由用如此复杂的方式来处理简单的数据


如果我没能说服你,原因很简单。您正在运行两个
查询,第一个查询不会触发任何插入ID。显然,您需要的是这个查询的元数据(错误、受影响的行等),而不是另一个查询的元数据。所以你明白了。要获取第二个查询的元数据,您必须向数据库查询。我的文章中解释了这个过程:。基本上,
PDOStatement::nextRowset()
就是您所需要的。

首先,我强烈建议在不同的API调用中运行每个查询。这就是应用程序编程接口的工作方式

它不仅可以防止出现这种情况,还可以使代码的可读性和可维护性大大提高

这也会使您的代码更加安全。您只能在一次调用中运行多个语句,而代价是本机准备的语句。不管这个漏洞多么虚拟,为什么要冒险呢

为什么不做一个常规的SELECT查询而不是SET,将结果值放入一个PHP变量中,然后通过占位符在其他变量中使用它呢?我看不出有什么理由用如此复杂的方式来处理简单的数据


如果我没能说服你,原因很简单。您正在运行两个
查询,第一个查询不会触发任何插入ID。显然,您需要的是这个查询的元数据(错误、受影响的行等),而不是另一个查询的元数据。所以你明白了。要获取第二个查询的元数据,您必须向数据库查询。我的文章中解释了这个过程:。基本上,
PDOStatement::nextRowset()
就是您所需要的。

Ah。很有道理。。。第一个查询提供行计数。丁。至于不把它们包装在一个单独的准备好的语句中,我基本上认为我只准备了一次就节省了周期,避免了延迟。。。它不是一个模拟语句(除非在一个PDO lexecution中对多个语句自动启动模拟…这是否意味着什么?)-使用SET而不是在SELECT中内联@var:=是否有任何性能损失?事实上,我用SET编写它是为了澄清查询的目的。我还对您的说法感到困惑,即在模拟模式下,“具有相同名称的占位符可以在同一查询中使用任意次数,而相应的变量只能绑定一次”,但它不适用于正常模式。AFAIK我没有在仿真模式下运行任何这些,我能够使用数组(“:var”=>$var)执行,其中“:var”在查询中多次出现,mysql没有任何错误。也许这在PHP7中刚刚得到支持?您使用的是仿真模式。您不保存任何周期。这两种方式都不会影响性能。性能是一个复杂的话题,您的关注点在这里完全是错误的。当我连接到数据库时,我有setAttribute(PDO::ATTR_EMULATE_PREPARES,false)。我如何使用仿真模式?啊。很有道理。。。第一个查询提供行计数。丁。至于不把它们包装在一个单独的准备好的语句中,我基本上认为我只准备了一次就节省了周期,避免了延迟。。。它不是一个模拟语句(除非在一个PDO lexecution中对多个语句自动启动模拟…这是否意味着什么?)-使用SET而不是在SELECT中内联@var:=是否有任何性能损失?事实上,我用SET编写它是为了澄清查询的目的。我还对您的说法感到困惑,即在模拟模式下,“具有相同名称的占位符可以在同一查询中使用任意次数,而相应的变量只能绑定一次”,但它不适用于正常模式。AFAIK我没有在仿真模式下运行任何这些,我能够使用数组(“:var”=>$var)执行,其中“:var”在查询中多次出现,mysql没有任何错误。也许这在PHP7中刚刚得到支持?您使用的是仿真模式。您不保存任何周期。这两种方式都不会影响性能。性能是一个复杂的话题,您的关注点在这里完全是错误的。当我连接到数据库时,我有setAttribute(PDO::ATTR_EMULATE_PREPARES,false)。我如何使用仿真模式?