在存储过程中循环准备语句查询的结果
Loop over results of prepared statement query inside stored procedure
我有一个存储函数,它的工作是遍历和分析来自多个表的大量数据。虽然大多数表是静态的——我可以声明游标来遍历数据——但有一些表是事先不知道的,特别是语言集表(例如 language_en
、language_fr
等)也就是说,在编写存储函数时,我不知道这些表中的哪一个会出现。
在存储函数本身中,我可以这样做:
declare cLang cursor for
SELECT table_name FROM information_schema.tables
WHERE table_schema=database() and table_name like 'language_%';
declare continue handler for not found set exit_loop = true;
open cLang;
set exit_loop = false;
cLang_loop: loop
fetch cLang into str;
...
end loop;
这样,我就可以遍历数据库中存在的所有语言表。然后我需要从他们每个人那里获取数据并循环进行分析。显然,我不能为它们中的每一个都声明一个游标,因为我不知道那里有哪些表。不过我可以使用准备好的语句:
fetch cLang into tableName;
set @stmt_text = concat("SELECT t_code, t_string FROM ", str);
prepare stmt from @stmt_text;
execute stmt using @scId;
但是现在,我该如何遍历此查询的结果?
我最后的做法是这样的。我没有创建动态游标来查询 table,而是有一个预定义的临时 table 并在该 table 上声明了一个游标。然后动态 sql 插入临时 table 并且常规游标遍历它。像这样:
declare cLang cursor for
SELECT table_name FROM information_schema.tables WHERE table_schema=database() and table_name like 'language_%';
declare cCode cursor for
SELECT t_code, t_string FROM tmp_lang;
declare continue handler for not found set exit_loop = true;
open cLang;
set exit_loop = false;
cLang_loop: loop
fetch cLang into str;
if exit_loop then
close cLang;
leave cLang_loop;
else
create temporary table tmp_lang (t_code varchar(50), t_string varchar(2000));
set @stmt_text = concat(
'insert into tmp_lang (t_code, t_string) SELECT t_code, t_string
from ', str);
prepare stmt from @stmt_text;
execute stmt;
if (select count(1) from tmp_lang) > 0 then
open cCode;
cCode_loop: loop
fetch cCode into lCode, lString;
if exit_loop then
close cCode;
set exit_loop = false;
leave cCode_loop;
else
-- now I can do whatever I need with the data
end if;
end loop;
end if;
deallocate prepare stmt;
drop table tmp_lang;
end if;
end loop;
我有一个存储函数,它的工作是遍历和分析来自多个表的大量数据。虽然大多数表是静态的——我可以声明游标来遍历数据——但有一些表是事先不知道的,特别是语言集表(例如 language_en
、language_fr
等)也就是说,在编写存储函数时,我不知道这些表中的哪一个会出现。
在存储函数本身中,我可以这样做:
declare cLang cursor for
SELECT table_name FROM information_schema.tables
WHERE table_schema=database() and table_name like 'language_%';
declare continue handler for not found set exit_loop = true;
open cLang;
set exit_loop = false;
cLang_loop: loop
fetch cLang into str;
...
end loop;
这样,我就可以遍历数据库中存在的所有语言表。然后我需要从他们每个人那里获取数据并循环进行分析。显然,我不能为它们中的每一个都声明一个游标,因为我不知道那里有哪些表。不过我可以使用准备好的语句:
fetch cLang into tableName;
set @stmt_text = concat("SELECT t_code, t_string FROM ", str);
prepare stmt from @stmt_text;
execute stmt using @scId;
但是现在,我该如何遍历此查询的结果?
我最后的做法是这样的。我没有创建动态游标来查询 table,而是有一个预定义的临时 table 并在该 table 上声明了一个游标。然后动态 sql 插入临时 table 并且常规游标遍历它。像这样:
declare cLang cursor for
SELECT table_name FROM information_schema.tables WHERE table_schema=database() and table_name like 'language_%';
declare cCode cursor for
SELECT t_code, t_string FROM tmp_lang;
declare continue handler for not found set exit_loop = true;
open cLang;
set exit_loop = false;
cLang_loop: loop
fetch cLang into str;
if exit_loop then
close cLang;
leave cLang_loop;
else
create temporary table tmp_lang (t_code varchar(50), t_string varchar(2000));
set @stmt_text = concat(
'insert into tmp_lang (t_code, t_string) SELECT t_code, t_string
from ', str);
prepare stmt from @stmt_text;
execute stmt;
if (select count(1) from tmp_lang) > 0 then
open cCode;
cCode_loop: loop
fetch cCode into lCode, lString;
if exit_loop then
close cCode;
set exit_loop = false;
leave cCode_loop;
else
-- now I can do whatever I need with the data
end if;
end loop;
end if;
deallocate prepare stmt;
drop table tmp_lang;
end if;
end loop;