2016-11-20 66 views
0

我有一個功能,即我根據如下的變量傳遞查詢數據:如何使用「IN」內部功能來查詢動態數據

CREATE OR REPLACE FUNCTION IR.SRG (
     IR_item  IN VARCHAR2, 
     IR_comp   VARCHAR2, 
     IR_locn   VARCHAR2, 
     IR_Type   VARCHAR2, 
     IR_fromdate   DATE, 
     IR_tilldate   DATE 
    ) 
     RETURN NUMBER 
     DETERMINISTIC 
    IS 
     IR_qty NUMBER; 
    BEGIN 

     IF IR_Type = 'O' 
     THEN 
      SELECT SUM(QTY) 
       INTO IR_qty 
       FROM STOCK_LEDGER 
      WHERE       
      ITEM_CODE = IR_item  AND 
        LOCATION_CODE IN 
           DECODE(IR_locn, 
           'ALL', 
           '(' 
           || '''D2'', ''D4'', ''D5'', ''D11''' 
           || ')', 
           '(' || IR_locn || ')') 

        AND DOCUMENTDATE <= IR_TILLDATE 
     AND DOCUMENTDATE >= IR_FROMDATE; 
     END IF; 

    RETURN (NVL (IR_QTY, 0)); 
EXCEPTION 
    WHEN ZERO_DIVIDE 
    THEN 
     RETURN 0; 
END; 
/

如果用戶爲IR_locn通過D2參數,那麼查詢應該針對該特定位置運行,如果用戶通過ALL,則查詢應該按照指定的四個位置D2, D4, D5,D11運行。

我不能通過使用IN來實現它,數據不會返回任何記錄。

我試着運行查詢使用DUALIN子句的格式看起來很好。

Select DECODE ('ALL', 
         'ALL', 
         '(' 
         || '''D2'', ''D4'', ''D5'', ''D11''' 
         || ')', 
         '(' || 'D5' || ')' 
        ) FROM DUAL 

我得到如下就像我跟ALL運行它的結果:

('D2', 'D4', 'D5', 'D11') 

回答

1

如果問題仍然相關!我只是找到了解決問題的方法,您創建了一個Oracle定義的集合。

CREATE OR REPLACE FUNCTION IR.SRG(
    IR_item IN VARCHAR2, 
    IR_comp  VARCHAR2, 
    IR_locn  VARCHAR2, 
    IR_Type  VARCHAR2, 
    IR_fromdate DATE, 
    IR_tilldate DATE, 
) 
RETURN NUMBER DETERMINISTIC 
IS 
    IR_qty NUMBER; 
    myLocations sys.odcivarchar2list; --collection 
BEGIN 
    if IR_TYPE  = 'O' then 
    IF IR_locn = 'ALL' THEN 
     myLocations := SYS.ODCIVARCHAR2LIST('D2','D4','D5','D11'); 
    ELSE 
     myLocations := SYS.ODCIVARCHAR2LIST('D2'); 
    END IF; 
    SELECT SUM(QTY) 
    INTO IR_qty 
    FROM STOCK_LEDGER 
    WHERE ITEM_CODE = IR_item 
    AND LOCATION_CODE IN 
    (SELECT column_value FROM TABLE(myLocations) 
) 
    AND DOCUMENTDATE <= IR_TILLDATE 
    AND DOCUMENTDATE >= IR_FROMDATE; 
END IF; 
RETURN (NVL (IR_QTY, 0)); 
EXCEPTION 
    WHEN ZERO_DIVIDE THEN 
    RETURN 0; 
END; 

的解決方案是從這個鏈接採取:Oracle PL/SQL - How to create a simple array variable?

+0

讓我試試看。謝謝 – user3625561

+0

注意: MyLocations:= SYS.ODCIVARCHAR2LIST('D2'); 'D2'必須由IR_locn替換。 – Mohamad

+0

我嘗試了上述,它工作正常。謝謝。 – user3625561

0

難道這個邏輯你想要做什麼?

WHERE ITEM_CODE = IR_item AND 
     DOCUMENTDATE <= IR_TILLDATE AND 
     DOCUMENTDATE >= IR_FROMDATE AND 
     (LOCATION_CODE = IR_locn OR IR_locn = 'ALL') 
+0

我想用「ALL」作爲標識符來查詢多個位置,並在數據級沒有什麼所謂的「ALL」。在查詢來自應用程序的數據時,用戶將輸入單個位置代碼或'ALL'。 – user3625561

+0

@ user3625561。 。 。這是這個答案實現的邏輯 - 假設'IR_locn'是用戶輸入。 –

0

您可以創建一個VARCHAR2變量(All_IR_locn),它包含字符串if語句的結果:

If IR_locn = 'ALL' then 

    All_IR_locn := ''D2','D4','D5','D11''; 

Else 

    All_IR_locn := IR_locn; 

End If; 

在查詢您更換:

DECODE(IR_locn, 
          'ALL', 
          '(' 
          || '''D2'', ''D4'', ''D5'', ''D11''' 
          || ')', 
          '(' || IR_locn || ')') 

通過

(All_IR_locn) 

Hope thi s可以幫助

+0

單引號出錯,所以我用雙引號All_IR_locn:= '''D2'',''D4'',''D5'',''D11''';但它不會返回任何數據,與以前一樣。 – user3625561

+0

您是否直接從SQL Developper(TOAD或您用於運行查詢的設備)執行查詢以查看是否有任何結果? SELECT SUM(QTY) INTO IR_qty FROM STOCK_LEDGER WHERE ITEM_CODE = IR_item AND LOCATION_CODE IN( 'D2', 'D4', 'D5', 'D11') AND DOCUMENTDATE <= IR_TILLDATE AND DOCUMENTDATE> = IR_FROMDATE; – Mohamad

+0

如果我直接指定代碼(如運行靜態查詢),查詢將運行,它將輸出正確的數據,但問題是執行查詢時使用解碼或功能。 – user3625561