Можно ли реорганизовать этот цикл хранимых процедур MySQL? - PullRequest
1 голос
/ 14 июля 2009

У меня есть цикл в хранимой процедуре 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 ]

1 голос
/ 14 июля 2009

попробуйте это:

 INSERT INTO foobar (foo_column, , ....)
    SELECT foo, ..., foo123
    FROM bar
    WHERE foo is something ...
0 голосов
/ 14 июля 2009

Это не просто проблема MySQL, она возникает в любой прилично большой СУБД (конечно, исключая Access). То, что вы описываете, называется «Установить логику». Что такое «если» и цикл делает то, чего не хватает в предложении «где»? Изменяется ли исходная информация с течением времени, и цикл по существу опрашивается? Если это так, вам все равно понадобится какой-то цикл, но вам лучше использовать условие where, чтобы получить как можно больше строк, вставленных за один раз, а затем создать цикл, который позволит вам обновляться с течением времени. Этот тип цикла, вероятно, лучше, если он находится вне вашего хранимого процесса. Другой ответ уже дал общий SQL, который я бы предложил.

0 голосов
/ 14 июля 2009

как насчет построения подготовленного оператора и его выполнения после цикла

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;

Josh

0 голосов
/ 14 июля 2009

Вы уверены, что вам нужно перебрать "SELECT foo FROM bar" таким образом ...

Нет ли способа сделать

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

??

...