使用 PHP 执行多个 MYSQL 查询

Posted

技术标签:

【中文标题】使用 PHP 执行多个 MYSQL 查询【英文标题】:Using PHP to execute multiple MYSQL Queries 【发布时间】:2021-10-30 10:26:06 【问题描述】:

我正在尝试使用 php 运行连续的 mysql 语句,如下面的代码 sn-p 所示(它只是将一行复制到另一行并通过 tmp 表重命名 id)。

我收到重复的语法错误消息。我已经尝试了无数次迭代。并且代码看起来像我在 PHP 手册和其他关于 SO(不包括 php 维度)的 myql 问题中研究过的代码。

谁能解释一下为什么我的 php 语法不正确?

 include("databaseconnect.php");// This obviously works. Used a zillion time

$sql ="CREATE TEMPORARY TABLE tmp SELECT * FROM event_categoriesBU WHERE id 
 = 1;";
$sql.="UPDATE tmp SET id=100 WHERE id = 1;";
$sql.="INSERT INTO event_categoriesBU SELECT * FROM tmp WHERE id = 100;";


if ($conn->query($sql) === TRUE) 
 
  echo "Table row copied successfully. Do something with it";
  
 else 
 
  echo "Error creating table: " . $conn->error;
  //close connection etc
 

PHP 消息返回:

创建表时出错:您的 SQL 语法有误;检查与您的 MariaDB 服务器版本相对应的手册,以在第 1 行的“UPDATE tmp SET id=100 WHERE id = 1INSERT INTO event_categoriesBU SELECT * FROM t”附近使用正确的语法

【问题讨论】:

使用 $conn->multi_query($sql) php.net/manual/en/mysqli.multi-query.php 【参考方案1】:

不要一次运行一堆查询。通常一个人的成功取决于所有其他操作是否正确执行,所以当出现问题时,你不能只是推土机,就好像什么都没出错一样。

你可以这样做:

$queries = [
  "CREATE TEMPORARY TABLE tmp SELECT * FROM event_categoriesBU WHERE id = 1",
  "UPDATE tmp SET id=100 WHERE id = 1",
  "INSERT INTO event_categoriesBU SELECT * FROM tmp WHERE id = 100"
];

foreach ($query as $query) 
  $stmt = $conn->prepare($query);
  $stmt->execute();

不要忘记enable exceptions,这样任何查询失败都会停止您的进程,而不是让事情失控。

使用multi_query 的原因是该函数不支持占位符值。如果您需要在此查询中引入某种类型的用户数据,您需要使用bind_param 以便安全地执行此操作。如果没有占位符值,您将面临 SQL 注入错误,其中一个就足以使您的整个应用程序易受攻击。

值得注意的是,PDO 比 mysqli 更加灵活和适应性强,所以如果您对 mysqli 的投入不是太大,那么值得考虑切换。

【讨论】:

据我所知 PDO 不支持多语句,所以你是不是建议不要使用多语句? 是的,现在切换到 PDO 的工作太大了。这是一项需要花费巨资才能改变的遗产 这是一个特性,而不是一个错误。 multi_query 函数是过去许多引人注目的安全漏洞背后的罪魁祸首,部分原因是您不仅可以 SQL 注入东西,而且您可以添加任意数量的语句,使其成为完美的游乐场攻击者。不要仅仅因为这个原因而使用multi_query,但另一个是您必须检查您运行的每个语句是否成功,然后再继续执行下一个。 mysqli 可以安全使用,但使用起来不太友好。例如,bind_param 需要仔细拼写其参数。 PDO 的通用 execute 函数可以接受一个数组,从而在处理可选参数时更容易使用。【参考方案2】:

query($sql) 不能执行多个 SQL 语句,必须使用 multi_query($sql)。然后你的脚本会变成这样:

if ($conn->multi_query($sql) === TRUE) 

    echo "Table row copied successfully. Do something with it";
 

有关完整示例,请参阅documentation。


但是,请注意,正如其他用户在 cmets 中很好解释的那样,使用此方法同时执行多个查询可能存在潜在危险,应尽可能避免,尤其是在处理用户输入时。

如果您一次执行一个查询并检查其结果,而不是在一次调用中将所有查询分组,您可以更好地控制执行流程。

【讨论】:

此功能极其危险,不应使用。 或者,您也可以使用mysqli_multi_query($connection, $sql);。 Documentation @ w3schools. mysqli_multi_query 是完全相同功能的程序性改变自我。您已经链接到文档。 @tadman 你为什么不告诉大家为什么它非常危险。因为它是一个串联? 你可以使用multi_query,如果你正确地转义了字符串,你可以mysqli_real_escape_string($conn, $sql)

以上是关于使用 PHP 执行多个 MYSQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

具有多个查询的NodeJS mysql连接池

PHP:如果用户未按下提交按钮,Mysql 回滚多个查询(通过 ajax 完成)

通过 PHP 使用用户定义的变量运行多个 MySQL 查询

在 PHP 中使用多个数据库进行 PDO 连接查询

MySQL在一个查询中应用多个条件[重复]

如何在 Node 中使用 Promise 进行多个 mysql 查询