【问题标题】:MySQL insert multiple records with while loopMySQL使用while循环插入多条记录
【发布时间】:2016-02-29 02:03:11
【问题描述】:

我有一个简单的 HTML 表单和一些 php 变量,如下所示,用于使用 submit 方法将书籍详细信息提交到名为 Book 的 MySQL 表。 clcode 是一个自增字段。

$isbn =$_POST["isbn"]; 
$bno =$_POST["b_no"];
$bname =$_POST["b_name"];
$qty =$_POST["qty"]; 
$price =$_POST["price"]; 

并且需要根据数量插入记录。例如:- 如果数量=2, 它需要执行两次插入查询(应该插入 2 条具有自动增量 clcode 的相同记录)。如果数量=5, 它需要执行 5 次插入查询(应该插入 5 条具有自动增量 clcode 的相同记录)等等...我使用了存储过程和以下 SQL 查询来执行此操作。

$query ="CREATE PROCEDURE myproc()
    BEGIN
    DECLARE i int DEFAULT 0;
    DO
    INSERT INTO book (isbn, b_no, b_name, qty, price) VALUES ('$isbn', '$bno', '$bname', '$qty', '$price');
        SET i = i + 1;
WHILE i < $qty;
    END WHILE;
END";

$result = mysql_query($query) or die ( mysql_error());

但它返回一个语法错误。我无法理解我出了什么问题。请。任何人都可以帮助我...? Tnx。

【问题讨论】:

  • 您容易出现sql注入,请添加一些错误日志
  • 所以你说it is return a syntax error,但你不认为在这里发布你的问题是个好主意吗?
  • 如果 post qty 为 2,是否应该插入 qty = 1 的两行?我假设您的记录应该有 N 个最小比例为 1 的表行。
  • 你为什么要为此使用存储过程?
  • @Xtern 找到答案。我已经测试过了。

标签: php mysql


【解决方案1】:
[begin_label:] WHILE search_condition DO
    statement_list
END WHILE [end_label]

这是while循环的语法

例如:-

CREATE PROCEDURE dowhile()
BEGIN
  DECLARE i INT DEFAULT 0;

  WHILE i < $qty  DO
    INSERT INTO book (isbn, b_no, b_name, qty, price) VALUES ('$isbn', '$bno', '$bname', '$qty', '$price');
    SET i = i + 1;
  END WHILE;
END;

试试这个。

【讨论】:

  • @raveenanigam。但是在第 1 行返回语法错误,例如 -> 'DELIMITER $$ CREATE PROCEDURE myproc() BEGIN DECLARE i integer DEFAULT'
【解决方案2】:

您不想在查询中使用CREATE PROCEDURE。你只想INSERT。你真的应该只是在 php 中循环来执行一个准备好的语句来执行插入。

阅读有关使用 mysqli 准备语句的 PHP 文档。

【讨论】:

    【解决方案3】:
    $count = 0
    while($qty >= $count){
        //insertion code goes here...
        $count++
    }
    

    【讨论】:

      【解决方案4】:

      修改你的sql语句:

      $query = "DELIMITER $$
      
          CREATE PROCEDURE myproc() 
          BEGIN DECLARE i integer DEFAULT 0; 
          while (i< ".$qty.") do 
          begin 
          INSERT INTO book (isbn, b_no, b_name, qty, price) VALUES (".$isbn.", ".$bno.", ".$bname.", ".$qty.", ".$price."); SET i = i + 1; end; end while; 
          END $$
      
          DELIMITER" ;
      

      更多详情请访问:http://www.mysqltutorial.org/stored-procedures-loop.aspx

      【讨论】:

        【解决方案5】:

        创建表

        create table book (
          id int not null auto_increment,
          isbn VARCHAR(20) not null,
          b_no VARCHAR(20) not null,
          b_name VARCHAR(20) not null,
          qty INT not null,
          price decimal(8, 2) not null,
          primary key(id)
        );
        

        创建 SP

        DELIMITER //
        
        CREATE PROCEDURE proc_book (
          IN isbn VARCHAR(20),
          IN no VARCHAR(20),
          IN name VARCHAR(20),
          IN qty INT,
          IN price DECIMAL(8,2)
        )
        BEGIN
          DECLARE i INT DEFAULT 0;
          WHILE i < qty DO
          INSERT INTO book (isbn, b_no, b_name, qty, price) VALUES (isbn, no, name, qty, price);
          SET i = i + 1;
          END WHILE;
        END;
        
        DELIMITER ;
        

        测试 SP

        call proc_book('978-3-16-148410-0', '1', 'name1', 2, 10.00);
        

        表格中的数据

        +----+-------------------+------+--------+-----+-------+
        | id | isbn              | b_no | b_name | qty | price |
        +----+-------------------+------+--------+-----+-------+
        |  1 | 978-3-16-148410-0 | 1    | name1  |   2 | 10.00 |
        |  2 | 978-3-16-148410-0 | 1    | name1  |   2 | 10.00 |
        +----+-------------------+------+--------+-----+-------+
        

        从 PHP 调用 SP

        用mysqli代替mysql

        <?php 
        // input data should be filterd to prevent SQL injection etc.
        $isbn  = $_POST["isbn"];
        $bno   = $_POST["b_no"];
        $bname = $_POST["b_name"];
        $qty   = $_POST["qty"];
        $price = $_POST["price"];
        
        //connect to database
        $connection = mysqli_connect("hostname", "user", "password", "db", "port");
        
        //run the store proc
        $sql = "CALL proc_book('" . $isbn . "', '" . $bno . "', '" . $bname . "', " . $qty . ", " . $price . ")";
        $result = mysqli_query($connection, $sql) or die("Query fail: " . mysqli_error());
        ?>
        

        参考

        【讨论】:

        • 很好的解释...请检查this以及
        • @Zumry Mohamed 我也会添加此参考。
        • 如果您添加大量数量,您应该考虑实施事务。请找到 10000 数量的基准。
        【解决方案6】:

        创建一个程序来满足您的要求是没有意义的。

        假设它在第一次运行时工作,但创建程序在下一次运行时会显示错误,因为程序已经存在。

        您只需要多次运行插入查询,或者使用多个值构建插入查询并运行一次。 这是我认为你应该做的。

        1.for($i=0;$i< $qty;$i++){ $sql = "INSERT INTO table_name (field1,field2,fieldn) VALUES ('field-val1','field-val2','field-valn')"; $result = mysql_query($sql) or die ( mysql_error()); } 或接近2

        $sql = "INSERT INTO table_name (field1,field2,fieldn) VALUES";
        
        for($i=0;$i< $qty;$i++){
          $sql .= "('val1','val2','valn')";
          if($i < ($qty -1 )){
             $sql .=",";
           }
        
         }
        

        $result = mysql_query($sql) or die (mysql_error());

        【讨论】:

          【解决方案7】:

          在 SP 中有和没有事务的性能基准。

          1.) 没有交易。

          DELIMITER //
          
          CREATE PROCEDURE proc_book (
              IN isbn VARCHAR(20),
              IN no VARCHAR(20),
              IN name VARCHAR(20),
              IN qty INT,
              IN price DECIMAL(8,2)
          )
          BEGIN
              DECLARE i INT DEFAULT 0;
              WHILE i < qty DO
              INSERT INTO book (isbn, b_no, b_name, qty, price) VALUES (isbn, no, name, qty, price);
              SET i = i + 1;
              END WHILE;
          END;
          
          DELIMITER ;
          

          尝试添加 1000 数量(无交易)

          mysql> call proc_book('978-3-16-148410-0', '1', 'name1', 10000, 10.00);
          Query OK, 1 row affected (8 min 43.01 sec)
          

          2.) 交易。

          DELIMITER //
          
          CREATE PROCEDURE proc_book (
              IN isbn VARCHAR(20),
              IN no VARCHAR(20),
              IN name VARCHAR(20),
              IN qty INT,
              IN price DECIMAL(8,2)
          )
          BEGIN
          
              DECLARE i INT DEFAULT 0;
          
              DECLARE EXIT HANDLER FOR SQLEXCEPTION
              BEGIN
                  ROLLBACK;
              END;
          
              DECLARE EXIT HANDLER FOR SQLWARNING
              BEGIN
                  ROLLBACK;
              END;
          
              START TRANSACTION;
          
              WHILE i < qty DO
                INSERT INTO book (isbn, b_no, b_name, qty, price) VALUES (isbn, no, name, qty, price);
                SET i = i + 1;
              END WHILE;
          
              COMMIT;
          
          END;
          
          DELIMITER ;
          

          尝试添加 1000 数量(含交易)

          call proc_book('978-3-16-148410-0', '1', 'name1', 10000, 10.00);
          Query OK, 0 rows affected (0.21 sec)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-04-19
            • 1970-01-01
            • 2015-01-14
            • 2019-08-08
            • 2022-01-07
            • 2013-02-03
            • 1970-01-01
            • 2023-04-03
            相关资源
            最近更新 更多