是否有可能重构这个MySQL存储过程循环?

时间:2009-07-14 12:37:24

标签: mysql stored-procedures loops

我在MySQL存储过程中有一个循环,其中我几乎为每次迭代插入记录。众所周知的问题是逐行插入是低效的,我宁愿看到带有多个值列表的插入。

当前程序的伪示例:

CREATE PROCEDURE p_foo_bar()
BEGIN
  DECLARE foo VARCHAR(255);
  DECLARE my_cursor CURSOR FOR SELECT foo FROM bar;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET not_found = 1;

  cursor_loop:
  LOOP
    FETCH my_cursor INTO foo;

    IF not_found THEN
      CLOSE my_cursor;
      LEAVE
    END IF;

    IF foo is something ... THEN
      INSERT INTO foobar (foo_colum) VALUES (foo);

      -- Anyone knows if it is possible to do bulk insert here:
      -- For example:
      -- INSERT INTO foobar (foo_column) VALUES (foo), ..., (foo123);
    END IF;
  END LOOP cursor_loop;
END

我宁愿看INSERT查询一段时间来增加它的值列表,然后定期在批量中插入,但如果没有烹饪一大碗意大利面,就无法看到方法。

4 个答案:

答案 0 :(得分:1)

试试这个:

 INSERT INTO foobar (foo_column, , ....)
    SELECT foo, ..., foo123
    FROM bar
    WHERE foo is something ...

答案 1 :(得分:0)

你确定你需要以这种方式迭代“SELECT foo FROM bar”......

没有办法吗

insert into foobar (foo_column) 
select foo 
  from bar 
  where foo is something

...

答案 2 :(得分:0)

如何构建一个准备好的语句并在循环之后执行它

http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html

declare @column_names text;
declare @column_values text;

然后在内圈添加你的 列名称和变量值

循环结束后,您可以构建查询并执行

set @sql_text = CONCAT('INSERT INTO foobar (', @column_names, 
                 ') VALUES (', @column_values, ')';

prepare stmt from @sql_text;

execute stmt;

约什

答案 3 :(得分:0)

这不仅仅是一个MySQL问题,它发生在任何体面的大型RDBMS中(当然,Access除外)。您描述的内容称为“设置逻辑”。什么是'if'和循环做一个好的where子句没有?源信息是否随时间而变化,循环基本上是轮询?如果这是真的,你仍然需要某种循环,但你最好使用where子句来尽可能多地插入行,然后创建一个循环,让你随着时间的推移更新。这种类型的循环可能最好不在你的存储过程之外。另一个答案已经给出了我建议的一般SQL。