我有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
.....等)得到了部分内容,但这确实是疯狂。
有人有不同的建议吗?这种愚蠢的设置是不久前做出的架构决策的结果。
谢谢!
答案 0 :(得分:4)
我同意您必须重新考虑您的数据库结构。 顺便说一句,只是为了好玩:)
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 :(得分:1)
不是真的。您不能使用相同名称的可变数量的参数或过程。
我不认为你的问题有一个简单的解决方案。
编辑:我想到了一个非常丑陋的解决方案,但如果您想使用它,我会留给您。这是未经测试的伪代码。创建一个proc,其中包含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//
列出所有表格。至少你不必列出可能的排列,程序的用户也不会知道你是怎么做的:)