2017-08-24 26 views
0

我有一個sp基於while條件遞歸運行。但條件不符合預期。雖然條件在我的sql

BEGIN 
declare moduleid VARCHAR(3); 
declare parent VARCHAR(3); 
declare flag int DEFAULT 0; 

SET max_sp_recursion_depth = 3; 
set moduleid = mdlid; 
set parent = ''; 
set flag  = 0; 

select moduleid; 

set parent = (
    select 
     ms.parentModule as parentModule 
    from 
     x ms 
    where 
     ms.moduleid = moduleid 
); 

select parent; 

set flag = if('MNU' = parent, 0, 1); 

select flag; 

while (flag <> 0) DO 

    select 
     ms.menuname 
    from 
     x ms 
    where 
     ms.moduleId = parent; 

    select 'called recursive'; 

    call usp_testwhile(parent); 

end WHILE; 

END 

儘管標誌值爲0執行中的內部語句。

此sp的初衷是當父母是MNU時停止。 對於例如x的表結構如下,

moduleid parentmodule menuname 
aaa   bbb   alpha1 
bbb   ccc   alpha2 
ccc   MNU   alpha3 

預期功能是 呼叫spname( 'AAA');

現在模塊ID是aaa,父母是bbb。在我檢查父項時= ='MNU'條件失敗並且週期2開始

現在模塊ID是bbb,父母是ccc。當我檢查父母!='MNU'條件失敗,週期3開始

現在模塊ID是ccc,父母是MNU。在我檢查父母時!='MNU'條件滿足,應該停止執行。

+2

你'flag'變量不是靜態的或全球性的 - 這是本地的存儲過程的範圍 - 如果從自身調用存儲過程的再flag'的'一個新實例(和'moduleid','parent'和' max_sp_recursion_depth')將被創建。您需要傳遞深度指標作爲參數。 – Dai

+0

@戴,這肯定是正確的答案,那麼爲什麼不把它作爲一個呢? –

回答

0

您定義不傳遞給遞歸調用的標誌變量,它只有在每個過程調用

我建議更新此調用的範圍內是否存在: 呼叫usp_testwhile(父); 實際上以某種方式包含標誌。或者,也可以刪除標誌變量,直接在while循環中執行Parent ='MNU'檢查。

對於您在此處定義的所有變量也是如此,如果您沒有將它們傳遞給遞歸調用,那麼它們將在每次遞歸調用時被有效地重置。

+0

如上所示,直接在while循環中檢查標記變量並且檢查父級別。仍存在問題 BEGIN declare parent VARCHAR(3); SET max_sp_recursion_depth = 3; select mdlid; set parent =( select ms.parentModule as parentModule from modulestructure ms where ms.moduleid = mdlid ); 選擇父項; while(parent <>'MNU')DO select ms.menuname from modulestructure ms where ms.moduleId = parent; call usp_testwhile(parent); 結束WHILE; END –

+0

根據您的評論更新了上面的答案 – OCDan

0

上述問題的解決方案是通過條件來實現的。 在上面的代碼while循環不能按預期工作。

if (parent != 'MNU') then 
set @menuname=(select 
    ms.menuname 
from 
    x ms 
where 
    ms.moduleId = parent); 
#select @menuname; 
set @conMenu = CONCAT(@menuname,COALESCE(menuname, '')); 

select @conMenu; 
call usp_testwhile(parent,@conMenu); 
end if;