数据库中有多张结构相同的表,这些表的名称具有相同的前缀。比如:
xxxxxxxxxxmysql> use testDatabase changed
mysql> show tables;+----------------+| Tables_in_test |+----------------+| url_01 || url_02 || url_03 || url_04 || url_05 |+----------------+5 rows in set (0.00 sec)
mysql> show create table url_01\G*************************** 1. row *************************** Table: url_01Create Table: CREATE TABLE `url_01` ( `url` varchar(1024) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci1 row in set (0.00 sec)现在向其中插入若干测试数据:
xxxxxxxxxxinsert into url_01(url) values("http://01.com/100"),("http://01.com");insert into url_02(url) values("http://02.com/100"),("http://02.com");insert into url_03(url) values("http://03.com/100"),("http://03.com");insert into url_04(url) values("http://04.com/100"),("http://04.com");insert into url_05(url) values("http://05.com/100"),("http://05.com");要求:查出所有表中 url 字段中包含 100 的记录。
下面提供一个纯 SQL 实现。
xxxxxxxxxxdelimiter $$
create procedure testproc(in result_sql text)begin declare expected_table_name varchar(1024); -- 期望的表名 declare tmp text default ""; -- 临时字符串 declare done int default false; -- 是否遍历到结束 -- 从 information_schema 中查找符合模式的表 declare testcur cursor for select Table_Name from information_schema.TABLES where TABLE_SCHEMA="test" and TABLE_NAME regexp "^url_"; declare continue handler for not found set done = True;
open testcur;
read_loop: loop fetch testcur into expected_table_name; if done then leave read_loop; end if;
select concat("select * from ", expected_table_name, " where url like '%100%'") into tmp; if @result_sql = "" then select tmp into @result_sql; else select concat(@result_sql, " union all ", tmp) into @result_sql; end if; end loop; close testcur;
prepare stmt from @result_sql; execute stmt;end$$
delimiter ;
set @result_sql = "";call testproc(@result_sql);select @result_sql\G
drop procedure testproc; -- 删除