2013-08-06 13 views
2

假設我有一個只公開公開一個過程的包。但是,此過程的目的是根據傳遞給它的參數在包中調用私有過程。從包中動態調用私有過程

理想情況下,我希望定義一個哈希表(例如,關聯數組甚至表)映射參數的內部程序,然後像做:

execute immediate 'begin ' || internalProc(myArgument) || '; end;'; 

然而,此次榮獲」因爲在包的範圍之外執行了動態的PL/SQL塊。我甚至不能做'begin myPkg.' || internalProc...,因爲內部程序都是私人的。

因此,我能做到這一點(不暴露私人程序)的唯一方法是通過一個大規模的硬編碼開關?

case myArgument 
    when 'something' then someProc; 
    when 'foo'  then fooProc; 
    when 'bar'  then barProc; 
    ... 
    else raise_application_error('-20001, 'No such process.') 
end case; 
+0

鑑於您必須將參數顯式映射到內部程序*某處*爲什麼大量的case語句如此有問題? – APC

+0

@APC有趣的是,我會說一個將參數映射到過程的表格*稍微容易維護。人們也可以使用內部程序的命名約定,以便有直接的對應關係(例如,'something'' - >'somethingProc','foo'' - >'fooProc'等) – Xophmeister

+1

我想我們有「可維護」的不同定義。我更喜歡將自己的控制邏輯放在我面前,而不必去別處看。另外,將參數值鏈接到內部過程的名稱會違反Demeter法則:http://en.wikipedia.org/wiki/Law_of_Demeter這意味着重新組織被調用程序的* internal *結構可能會產生影響在呼叫方案,這是可維護的(根據我的經驗,YMMV)相反。 – APC

回答

2

PL/SQL是一種過程式語言,並不是特別擅長動態執行自己。它與Java的Reflection功能毫無相似之處。因此,實施你提出的建議最多是笨重的。

接下來的問題是你提出的是否是一個好主意。這是個人品味的問題。我自己,我更喜歡把我的控制邏輯放在我面前,而不必去別處看。在軟編碼的某些外部對象中配置控制流:「從源代碼中刪除源代碼中的東西並將它們放置在某個外部資源中的做法。」 Find out more。軟編碼最多隻能將複雜性移到其他地方,最糟糕的是它增加了系統的整體複雜性。應用程序完全由這些東西構建而成,但是它們使用規則引擎來管理事物(並且有趣的是,某些應用程序似乎超出了人類的理解範圍)。

將參數值鏈接到內部過程的名稱將打破the Law of Demeter。這是一個非常明智的設計原則,認爲調用程序不應該理解被調用程序的內部結構。違反德米特法則意味着重新組織被調用程序的內部結構可能會對調用程序產生影響。這對可維護性產生不利影響(以我的經驗,YMMV)。

TL;博士
大CASE語句是a bit like democracy:他們除了所有其他最壞的解決方案。