【问题标题】:Insert multiple rows with one query MySQL一次查询 MySQL 插入多行
【发布时间】:2012-09-12 04:39:31
【问题描述】:

我想编写脚本,具有多个插入查询的功能。 让我更好地解释一下。

我有一个quantity 以html 形式输入。 我有 MySQL 查询将registered user 插入表中。 所以我希望我的函数为“数量”时间插入此查询。

 mysql_query("INSERT INTO `pxlot` (realname,email,address,phone,status,regtime,ip) 
 VALUES ('$realname','$email','$address','$phone','0','$dateTime','$ip')")
 or die (mysql_error()); // Inserts the user.

例如插入 3 次。 有什么建议?

【问题讨论】:

  • 如果您在给定表中多次重复同一行相同的值,那么您做错了。您需要返回并重新评估您的架构设计。
  • 顺便说一句 mysql_* 已被弃用

标签: php mysql


【解决方案1】:
 INSERT INTO table (a,b) VALUES (1,2), (2,3), (3,4);

http://dev.mysql.com/doc/refman/5.5/en/insert.html

【讨论】:

  • 语句中列值列表的限制是什么?我的意思是我们可以将多少个元组 (1,2) 传递到单个 INSERT 语句中。
  • @akshay,我真的不知道答案,我怀疑限制不在于元组的数量,而在于由max_allowed_packet mysql 系统变量控制的语句大小。我认为默认值是 1MB,协议最大 1GB。
【解决方案2】:

在大多数情况下,在 MySQL 中使用一条 Insert 语句插入多条记录比在 PHP 中使用 for/foreach 循环插入记录要快得多。

假设 $column1 和 $column2 是 html 表单发布的大小相同的数组。

您可以像这样创建查询:

<?php
    $query = 'INSERT INTO TABLE (`column1`, `column2`) VALUES ';
    $query_parts = array();
    for($x=0; $x<count($column1); $x++){
        $query_parts[] = "('" . $column1[$x] . "', '" . $column2[$x] . "')";
    }
    echo $query .= implode(',', $query_parts);
?>

如果为两条记录发布数据,查询将变为:

插入表(column1column2)值('data','data'),('data','data')

【讨论】:

    【解决方案3】:

    这里有一些方法可以做到这一点

    INSERT INTO pxlot (realname,email,address,phone,status,regtime,ip) 
    select '$realname','$email','$address','$phone','0','$dateTime','$ip' 
    from SOMETABLEWITHTONSOFROWS LIMIT 3;
    

    INSERT INTO pxlot (realname,email,address,phone,status,regtime,ip) 
    select '$realname','$email','$address','$phone','0','$dateTime','$ip'
    union all select '$realname','$email','$address','$phone','0','$dateTime','$ip'
    union all select '$realname','$email','$address','$phone','0','$dateTime','$ip'
    

    INSERT INTO pxlot (realname,email,address,phone,status,regtime,ip) 
    values ('$realname','$email','$address','$phone','0','$dateTime','$ip')
    ,('$realname','$email','$address','$phone','0','$dateTime','$ip')
    ,('$realname','$email','$address','$phone','0','$dateTime','$ip')
    

    【讨论】:

      【解决方案4】:

      虽然使用单个 INSERT 语句插入多行通常更快,但它会导致更复杂且通常不安全的代码。下面我将介绍使用 PHP 一次性插入多条记录的最佳实践。

      要同时向数据库中插入多条新行,需要遵循以下 3 个步骤:

      1. 启动事务(禁用自动提交模式)
      2. 准备INSERT声明
      3. 多次执行

      使用数据库事务可确保数据保存在一块并显着提高性能。

      如何使用 PDO 正确插入多行

      PDO 是 PHP 中最常见的数据库扩展选择,使用 PDO 插入多条记录非常简单。

      $pdo = new \PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", 'user', 'password', [
          \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
          \PDO::ATTR_EMULATE_PREPARES => false
      ]);
      
      // Start transaction
      $pdo->beginTransaction();
      
      // Prepare statement
      $stmt = $pdo->prepare('INSERT 
          INTO `pxlot` (realname,email,address,phone,status,regtime,ip) 
          VALUES (?,?,?,?,?,?,?)');
      
      // Perform execute() inside a loop
      // Sample data coming from a fictitious data set, but the data can come from anywhere
      foreach ($dataSet as $data) {
          // All seven parameters are passed into the execute() in a form of an array
          $stmt->execute([$data['name'], $data['email'], $data['address'], getPhoneNo($data['name']), '0', $data['regtime'], $data['ip']]);
      }
      
      // Commit the data into the database
      $pdo->commit();
      

      如何使用mysqli正确插入多行

      mysqli 扩展使用起来有点麻烦,但操作原理非常相似。函数名称不同,参数略有不同。

      mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
      $mysqli = new \mysqli('localhost', 'user', 'password', 'database');
      $mysqli->set_charset('utf8mb4');
      
      // Start transaction
      $mysqli->begin_transaction();
      
      // Prepare statement
      $stmt = $mysqli->prepare('INSERT 
          INTO `pxlot` (realname,email,address,phone,status,regtime,ip) 
          VALUES (?,?,?,?,?,?,?)');
      
      // Perform execute() inside a loop
      // Sample data coming from a fictitious data set, but the data can come from anywhere
      foreach ($dataSet as $data) {
          // mysqli doesn't accept bind in execute yet, so we have to bind the data first
          // The first argument is a list of letters denoting types of parameters. It's best to use 's' for all unless you need a specific type
          // bind_param doesn't accept an array so we need to unpack it first using '...'
          $stmt->bind_param('sssssss', ...[$data['name'], $data['email'], $data['address'], getPhoneNo($data['name']), '0', $data['regtime'], $data['ip']]);
          $stmt->execute();
      }
      
      // Commit the data into the database
      $mysqli->commit();
      

      性能

      这两个扩展都提供了使用事务的能力。使用事务执行准备好的语句极大地提高了性能,但它仍然不如单个 SQL 查询。然而,差异是如此微不足道,以至于为了简洁和干净的代码,多次执行准备好的语句是完全可以接受的。如果您需要一个更快的选项来一次将多条记录插入数据库,那么 PHP 可能不是正确的工具。

      【讨论】:

        【解决方案5】:

        如果您想插入多个值,比如说从具有不同 post 值但要插入到同一个表中的多个输入中,那么只需使用:

        mysql_query("INSERT INTO `table` (a,b,c,d,e,f,g) VALUES 
        ('$a','$b','$c','$d','$e','$f','$g'),
        ('$a','$b','$c','$d','$e','$f','$g'),
        ('$a','$b','$c','$d','$e','$f','$g')")
        or die (mysql_error()); // Inserts 3 times in 3 different rows
        

        【讨论】:

          猜你喜欢
          • 2015-05-02
          • 2012-12-16
          • 2020-12-25
          • 1970-01-01
          • 2016-08-13
          • 2017-06-05
          • 2016-03-25
          • 2012-04-21
          • 1970-01-01
          相关资源
          最近更新 更多