1

У меня есть хранимая функция, задача которой состоит в том, чтобы пройти и проанализировать много данных из нескольких таблиц. В то время как большинство таблиц статичны - и я могу объявлять курсоры для обработки данных - есть некоторые таблицы, которые заранее не известны, в частности, таблицы набора языков (например, 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; 

Но теперь, как мне выполнить цикл по результатам этого запроса?

+0

Опцион может быть динамическим курсором, см [MariaDB/MySQL: Курсоры для динамического SQL] (https://falseisnotnull.wordpress.com/2013/01/08/mariadbmysql-cursors- для-динамического SQL /). – wchiquito

ответ

0

То, как я закончил это, это. Вместо того, чтобы создавать динамический курсор для запроса таблицы, у меня есть предопределенная временная таблица и объявить курсор над этой таблицей. Затем динамический sql вставляет в таблицу temp, и над ним курсирует обычный курсор. Что-то вроде этого:

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;