簡體   English   中英

用於SQL語句的Oracle存儲過程本地數字集合

[英]Oracle stored procedure local collection of numbers for use in SQL statement

我正在嘗試查詢NUMBER的表或集合,並在單獨的查詢中的WHERE IN語句中使用該集合。 我覺得它應該很簡單,但我無法讓它工作。 我對 PL/SQL 非常陌生,並且花了幾天時間試圖找出解決方案,非常感謝任何幫助。

當我使用SYS.ODCINUMBERLIST時, INTO V_INVENTORY_ITEMS出現錯誤:

PL/SQL:ORA-00932:不一致的數據類型:預期的 UDT 得到了 NUMBER

如果我使用注釋掉的V_INVENTORY_ITEMS nested_typ來存儲集合,我會得到

95/21 PLS-00642:SQL 語句中不允許本地集合類型

似乎我不能在WHERE IN (...)子句中使用任何 IF 邏輯。

這是我正在嘗試做的一個非常簡化的版本:

CREATE OR REPLACE PROCEDURE GET_ITEMS(
P_CR OUT SYS_REFCURSOR,
IN_ITEM_TYPE VARCHAR2
)

IS

V_INVENTORY_ITEMS SYS.ODCINUMBERLIST;

--TYPE nested_typ IS TABLE OF NUMBER;
--V_INVENTORY_ITEMS   nested_typ;
BEGIN

IF IN_ITEM_TYPE  = 'TYPE1'
    SELECT ITEM_ID 
    INTO V_INVENTORY_ITEMS 
    FROM ITEM_MASTER
    WHERE CATEGORY = 'CAT1' OR CATEGORY = 'CAT2';
ELSE
    SELECT ITEM_ID 
    INTO V_INVENTORY_ITEMS 
    FROM ITEM_MASTER
    WHERE CATEGORY = 'CAT3' OR CATEGORY = 'CAT4';
END IF;

OPEN P_CR FOR
    SELECT * FROM ORDER_LINES
    WHERE ITEM_ID IN (V_INVENTORY_ITEMS )
END GET_ITEMS;

在子查詢中使用表集合表達式:

CREATE OR REPLACE PROCEDURE GET_ITEMS(
  P_CR         OUT SYS_REFCURSOR,
  IN_ITEM_TYPE     VARCHAR2
)
IS
  V_INVENTORY_ITEMS SYS.ODCINUMBERLIST;
BEGIN
  IF IN_ITEM_TYPE  = 'TYPE1'
    SELECT ITEM_ID 
    INTO V_INVENTORY_ITEMS 
    FROM ITEM_MASTER
    WHERE CATEGORY = 'CAT1' OR CATEGORY = 'CAT2';
  ELSE
    SELECT ITEM_ID 
    INTO V_INVENTORY_ITEMS 
    FROM ITEM_MASTER
    WHERE CATEGORY = 'CAT3' OR CATEGORY = 'CAT4';
  END IF;

  OPEN P_CR FOR
    SELECT * FROM ORDER_LINES
    WHERE ITEM_ID IN (SELECT column_value FROM TABLE(V_INVENTORY_ITEMS))
END GET_ITEMS;
/

或者,不要使用集合:

CREATE OR REPLACE PROCEDURE GET_ITEMS(
  P_CR         OUT SYS_REFCURSOR,
  IN_ITEM_TYPE     VARCHAR2
)
IS
BEGIN
  IF IN_ITEM_TYPE  = 'TYPE1'
    OPEN P_CR FOR
      SELECT * FROM ORDER_LINES
      WHERE ITEM_ID IN (
        SELECT ITEM_ID 
        FROM ITEM_MASTER
        WHERE CATEGORY = 'CAT1' OR CATEGORY = 'CAT2'
      );
  ELSE
    OPEN P_CR FOR
      SELECT * FROM ORDER_LINES
      WHERE ITEM_ID IN (
        SELECT ITEM_ID 
        FROM ITEM_MASTER
        WHERE CATEGORY = 'CAT3' OR CATEGORY = 'CAT4'
      );
  END IF;
END GET_ITEMS;
/

您可以完全繞過對IN_ITEM_TYPE的專門測試並減少到單個語句;

create or replace procedure get_items (p_cr         out sys_refcursor
                                     , in_item_type in  varchar2
                                     )
is
begin 
    open p_cr  for
         select ol.*
           from order_lines ol 
          where ol.item_id  in
                (select im.item_id
                   from item_master im
                  where im.type = in_item_type 
                    and (   (im.type = 'TYPE1' and im.category in ('CAT1','CAT2'))  
                         or (im.type = 'TYPE2' and im.category in ('CAT3','CAT4'))
                        )
                );
end get_items; 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM