【问题标题】:Loop over results of prepared statement query inside stored procedure在存储过程中循环准备语句查询的结果
【发布时间】:2017-06-09 21:25:07
【问题描述】:

我有一个存储函数,它的工作是遍历并分析来自多个表的大量数据。虽然大多数表都是静态的——我可以声明游标来遍历数据——但有些表是事先不知道的,特别是语言集表(例如language_enlanguage_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;

但是现在,我如何循环遍历这个查询的结果?

【问题讨论】:

标签: mysql loops stored-procedures prepared-statement stored-functions


【解决方案1】:

我最终这样做的方式是这样的。我没有创建动态游标来查询表,而是有一个预定义的临时表并在该表上声明一个游标。然后动态 sql 插入到临时表中,并且常规游标对其进行迭代。像这样的:

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;

【讨论】:

    猜你喜欢
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 2014-08-02
    • 2016-04-08
    • 1970-01-01
    相关资源
    最近更新 更多