Итерация без использования курсора в MYSQL - PullRequest
5 голосов
/ 23 ноября 2011

Я новичок в хранимых процедурах. Моя задача - написать хранимую процедуру, которая сначала проверит данные из временной таблицы, а затем вставит данные в основную таблицу. Для этого я планирую перебрать каждую строку временной таблицы, проверить ее с помощью другой хранимой процедуры или пользовательской функции, а затем вставить данные в основную таблицу.

Моя проблема заключается в том, как перебирать строки временной таблицы, не используя CURSORS, потому что они очень медленные и занимают много памяти. Я хочу использовать некоторую циклическую структуру вместо CURSOR.

Конечно, если у кого-то есть какой-либо другой алгоритм для вышеуказанной проблемы, то предложения приветствуются.

PS: я использую MYSQL DB

1 Ответ

5 голосов
/ 13 декабря 2011

Без использования Cursor вы можете выполнять итерации, используя временную таблицу и инструкцию While..Do.

Допустим, у вас есть две таблицы

CREATE TABLE `user` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(45) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM;

И

CREATE TABLE `tmp_user` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(45) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM;

Создайте следующую подпрограмму и настройте процесс проверки:

DELIMITER $$
USE `routines_sample`$$
CREATE PROCEDURE `nocursor`()
BEGIN
  Declare validId int;
  Declare validName varchar(45);

  -- drop the temporary table if exists
  Drop table if exists `routines_sample`.tmp_validation;
  -- create the temporary table, here you could use Engine=Memory
  Create table `routines_sample`.tmp_validation (`id` int not null, `name` varchar(45) not null, `valid` bit(1) not null) Engine=MyISAM;

  -- insert into the temporary table with a valid flag = 0 (false)    
  Insert into `routines_sample`.tmp_validation (`id`, `name`, `valid`)
  Select tu.id, tu.name, 0
  From `routines_sample`.tmp_user tu;

  -- while exists data to validate on temporary table do something    
  While exists(Select `id` From `tmp_validation` Where `valid` = 0) Do

    Select `id`, `name` Into @validId, @validName From tmp_validation Where `valid` = 0 Limit 1;

    -- do your validation
    Select @validId, @validName;

    -- don't forget to update your validation table, otherwise you get an endless loop    
    Update `tmp_validation` 
    Set `valid` = 1
    Where `id` = @validId;

  END WHILE;

  -- insert only valid rows to your destination table    
  Insert into `routines_sample`.`user` (`name`)
  Select `name` From `tmp_validation`
  Where `valid` = 1;

  -- drop the temporary table    
  DROP TABLE tmp_validation;

END$$

DELIMITER ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...