Sql 如何使用“IN”内部函数查询动态数据

Sql 如何使用“IN”内部函数查询动态数据,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,我有一个函数,根据传递的变量查询数据,如下所示: CREATE OR REPLACE FUNCTION IR.SRG ( IR_item IN VARCHAR2, IR_comp VARCHAR2, IR_locn VARCHAR2, IR_Type VARCHAR2, IR_fromdate DATE, IR_till

我有一个函数,根据传递的变量查询数据,如下所示:

    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;
/
我得到的结果如下所示,因为我正在运行它与所有:


这个逻辑符合你的要求吗

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

这个逻辑符合你的要求吗

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

您可以创建一个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 || ')')


希望这能有所帮助

您可以创建一个varchar2变量All\u IR\u 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 || ')')


如果问题仍然存在,希望这能有所帮助!我刚刚找到了解决您问题的方法,您可以创建一个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定义的集合

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;

解决方案取自此链接:

我想使用“ALL”作为标识符来查询多个位置,在数据级别没有所谓的“ALL”。从应用程序查询数据时,用户将输入单个位置代码或“全部”。@user3625561。这就是这个答案实现的逻辑——假设IR_locn是用户输入。我想使用'ALL'作为标识符来查询多个位置,在数据级别上没有所谓的'ALL'。从应用程序查询数据时,用户将输入单个位置代码或“全部”。@user3625561。这就是这个答案实现的逻辑——假设IR_locn是用户输入。单引号给出了一个错误,所以我使用了双引号All_IR_locn:='D2,D4,D5,D11';但它不返回任何数据,与以前一样。您是否直接从SQL Developer TOAD或用于运行查询的设备执行查询以查看是否有任何结果?从库存分类账中选择库存数量,其中“D2”、“D4”、“D5”、“D11”中的项目代码=库存项目,位置代码=库存起始日期;如果我直接将代码指定为运行静态查询,查询将运行并输出正确的数据,但问题是在使用decode或if函数执行查询时。单引号给出了一个错误,因此我使用双引号All_IR_locn:='D2,D4,D5,D11';但它不返回任何数据,与以前一样。您是否直接从SQL Developer TOAD或用于运行查询的设备执行查询以查看是否有任何结果?从库存分类账中选择库存数量,其中“D2”、“D4”、“D5”、“D11”中的项目代码=库存项目,位置代码=库存起始日期;如果我直接将代码指定为运行静态查询,那么查询将运行并输出正确的数据,但问题是在使用decode或if函数执行查询时。让我试试。感谢注意:MyLocations:=SYS.ODCIVARCHAR2LIST'D2';'D2’必须用IR_locn替换。让我试试。感谢注意:MyLocations:=SYS.ODCIVARCHAR2LIST'D2';'D2’必须用IR_locn替换。