2016-11-20 52 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