2017-04-10 25 views
0

嗨有一個具有9列具有相同數據類型(都是百分比值)的表。我試圖在PL \ SQL函數中創建一個Select語句,以返回3的元組,取決於外部參數值。如何使用相同的Select語句獲取不同的表列

在語法上,這樣的事情:

WITH tmp 
    AS (SELECT '1' col1, 
       '2' col2, 
       '3' col3, 
       '4' col4, 
       '5' col5, 
       '6' col6, 
       '7' col7, 
       '8' col8, 
       '9' col9 
      FROM DUAL 
     UNION 
     SELECT '10' col1, 
       '20' col2, 
       '30' col3, 
       '40' col4, 
       '50' col5, 
       '60' col6, 
       '70' col7, 
       '80' col8, 
       '90' col9 
      FROM DUAL 
     UNION 
     SELECT '100' col1, 
       '200' col2, 
       '300' col3, 
       '400' col4, 
       '500' col5, 
       '600' col6, 
       '700' col7, 
       '800' col8, 
       '900' col9 
      FROM DUAL) 
SELECT CASE 
      WHEN externaparameter = 1 THEN (col1, col2, col3) 
      WHEN externaparameter = 2 THEN (col4, col5, col6) 
      WHEN externaparameter = 3 THEN (col7, col8, col9) 
     END 
    INTO var1, var2, var3 
    FROM tmp; 

我有這兩種解決方案:

實現爲每列CASE語句。但它會創建一個大的選擇語句,可能會讓人困惑。

SELECT CASE 
      WHEN externaparameter = 1 THEN col1 
      WHEN externaparameter = 2 THEN col4 
      WHEN externaparameter = 3 THEN col7 
     END, 
     CASE 
      WHEN externaparameter = 1 THEN col2 
      WHEN externaparameter = 2 THEN col5 
      WHEN externaparameter = 3 THEN col8 
     END, 
     CASE 
      WHEN externaparameter = 1 THEN col3 
      WHEN externaparameter = 2 THEN col6 
      WHEN externaparameter = 3 THEN col9 
     END 
    INTO var1, var2, var3 
    FROM tmp; 

或者,用union實現三個select語句。但我最初的查詢有幾個WHERE條件,對於這種情況我需要重複它們。

SELECT a, b, c 
    INTO var1, var2, var3 
    FROM (SELECT col1 a, col2 b, col3 c 
      FROM tmp 
     WHERE externalparameter = 1 
     UNION 
     SELECT col4 a, col5 b, col6 c 
      FROM tmp 
     WHERE externalparameter = 2 
     UNION 
     SELECT col7 a, col8 b, col9 c 
      FROM tmp 
     WHERE externalparameter = 3) 

我對這個問題有更清晰的Select語句嗎?每種解決方案有哪些優點和缺點?

+1

這種方法聽起來有點狡猾。相反,我會考慮一個單一的過程,它會封裝一個返回所有行的單個SQL,然後用過程或過程來包裝這個過程來解釋parm並返回適當的行。 – unleashed

回答

1

如果在運行時基於externalparameter不能有選擇地運行三個單獨查詢中的一個,那麼使用case表達式的選項1是更清晰的解決方案。

問題與union解決方案:

  1. 檢查產生一定的查詢計劃,但我想它會執行三個獨立的SELECT語句雖然他們是互斥的。 (除非12c比查詢優化更聰明,至少我已經說過)。這是因爲該計劃可能會被重用,因此計劃必須包含所有三個選擇,以在所有情況下都具有正確的選擇。
  2. union版本包含一個隱式的不同,如果事情在第一個版本中已經不同,那麼它會添加工作。或者改變結果與第一個版本。

動態SQL有時用於這種情況,但我認爲三個靜態語句有選擇地運行會比創建一個動態SQL字符串更好。

相關問題