Объединение с переменным количеством таблиц.(Перегружена хранимая процедура MySQL) - PullRequest
1 голос
/ 09 декабря 2011

У меня есть 10 таблиц с одинаковой схемой.Я пытаюсь создать перегруженную хранимую процедуру, чтобы я мог объединить несколько таблиц вместе с простыми выборами (SELECT * FROM tableX).Если каждая таблица имеет 1000 (разных) строк, то я хочу создать хранимую процедуру, в которой произойдет следующее:

CALL getRowsByNum(table1); -> 1000 rows
CALL getRowsByNum(table1, table2, table4); -> 3000 rows

... и т. Д.

Я получил часть путинаписав 10 перегруженных процедур, которые SELECT * FROM X UNION ALL SELECT * FROM X UNION ALL ..... и т. д., но это действительно безумие .

У кого-нибудь есть другое предложение?Эта глупая установка - результат архитектурного решения, принятого некоторое время назад.

Спасибо!

Ответы [ 2 ]

4 голосов
/ 10 декабря 2011

Я согласен, что вы должны переосмыслить свою структуру БД. Кстати, просто для удовольствия:)

drop database if exists my_test;

create database my_test;

use my_test;

create table table1 (
id int not null auto_increment primary key,
my_field varchar(10)
) engine = myisam;

create table table2 like table1;
create table table3 like table1;
create table table4 like table1;
create table table5 like table1;

insert into table1 (my_field) values ('aaa'),('bbb');
insert into table2 (my_field) values ('ccc'),('ddd'),('eee');
insert into table3 (my_field) values ('fff'),('ggg');
insert into table4 (my_field) values ('hhh'),('iii'),('jjj');
insert into table5 (my_field) values ('kkk'),('lll');


delimiter //
drop procedure if exists tables_union //
create procedure tables_union (in str varchar(10000),in db varchar(100))
begin
set @qry = (select group_concat(concat('select * from ',table_name) separator ' union all ')
            from information_schema.tables
            where find_in_set(table_name,str) 
            and table_schema = db);
-- select @qry;
prepare stmt from @qry;
execute stmt;
deallocate prepare stmt;            

end; //
delimiter ;

call tables_union('table4,table3,table1','my_test');

+----+----------+
| id | my_field |
+----+----------+
|  1 | aaa      |
|  2 | bbb      |
|  1 | fff      |
|  2 | ggg      |
|  1 | hhh      |
|  2 | iii      |
|  3 | jjj      |
+----+----------+
7 rows in set (0.00 sec)
1 голос
/ 10 декабря 2011

Не совсем. Вы не можете иметь переменное количество параметров или процедур с одинаковым именем.

Я не думаю, что есть простое решение вашей проблемы.

РЕДАКТИРОВАТЬ: Я думал о действительно некрасивом решении, но я оставлю это вам, если вы хотите его использовать. Это только непроверенный псевдокод.

Создайте процесс, в котором вы берете varchar, достаточно долго, чтобы содержать значение "table1, table2, table3, ..." и т. Д. Для максимально возможного количества таблиц, которые вы хотите объединить. (может быть другой идентификатор, конечно)

Запишите все таблицы в объединении. Поскольку они одинаковые, просто используйте *, чтобы сэкономить время и пространство

delimiter //

create procedure megaunion (tables varchar(255)) 
begin 
   select * from table1 where find_in_set('table1', tables)   
   union
   select * from table2 where find_in_set('table2', tables)
   ....
end//

список всех ваших таблиц. По крайней мере, вам не нужно перечислять возможные перестановки, и пользователь процедуры не будет знать, как вы это сделали:)

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