понедельник, 4 февраля 2008 г.

Хранимые процедуры и динамические таблицы

Довольно часто возникает задача обработать одну или несколько таблиц с помощью одной и той же процедуры. Причем, передавая название таблицы в параметре процедуры.
MySQL не воспринимает зарпосы такого вида:

SET @mytable='users';
SELECT * FROM @mytable;


Обойти эту проблему можно так, вот пример процедуры выполняющие архивацию таблиц:

DELIMITER $$

DROP PROCEDURE IF EXISTS `mydb`.`create_archive`$$
CREATE DEFINER=`alex`@`%` PROCEDURE `create_archive`(
IN current_table VARCHAR(50)
)
BEGIN
DECLARE template,archive_template VARCHAR(50);
/* Если название таблицы было my_data
то получаем название архивной таблицы my_data_200802 */

SET archive_prefix='200802';
SET template=CONCAT(current_table,"_",archive_prefix);

/* Эта конструкция формирует запрос который будет выглядить так
CREATE TABLE my_data_200802 ENGINE_ARCHIVE
AS (SELECT * FROM my_data); */

SET @archive_query:=CONCAT
("CREATE TABLE ",template, " ENGINE=ARCHIVE AS
(SELECT * FROM ",current_table," )");

PREPARE archive_query FROM @archive_query;
EXECUTE archive_query;
DEALLOCATE PREPARE archive_query;

END$$

DELIMITER ;


Продолжение следует....

2 комментария:

Full Stack Daily комментирует...

Я тоже пробовал такое решение - но MySQL 5.0.x выдает сообщение об ошибке

Error Code : 1336
Dynamic SQL is not allowed in stored function or trigger
(0 ms taken)

MGYK комментирует...

Да динамический SQL нельзя использовать в функция и триггерах. Но возможно можно просто из самого приложения дергать процедуру, а не привязывать всю логику к триггеру.