1

我有一個存儲函數,它的工作是通過並分析來自多個表的大量數據。儘管大多數表格都是靜態的 - 而且我可以聲明光標以循環數據 - 但有一些表格不提前知道,具體而言,語言集合表格(例如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; 

但現在,我該如何循環查詢的結果?

+0

一種選擇可以是動態的光標,見[MariaDB的/ MySQL的:動態SQL遊標](https://falseisnotnull.wordpress.com/2013/01/08/mariadbmysql-cursors-對於動態-SQL /)。 – wchiquito

回答

0

我最終這樣做的方式是這樣的。我沒有創建一個動態遊標來查詢表,我有一個預定義的臨時表並在該表上聲明一個遊標。然後動態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; 
相關問題