2011-12-28 76 views
1

我有一個表變量傳遞給一個過程。我想在下面的where子句中使用這些值,我該怎麼做。下面的第一行是在包定義中聲明的。以下程序位於程序包主體中。Where Where子句中的PL/SQL使用表變量

type CatalogNos is table of VARCHAR2(100); 
PROCEDURE GET_PART_CHARACTERISTICS (v_catalog_nos_ IN CatalogNos, 
            Parts_Char_Cursor out sys_refcursor) AS 
BEGIN 
    OPEN Parts_Char_Cursor FOR 
    SELECT * FROM IFSAPP.SALES_PART_CHARACTERISTIC 
    WHERE CATALOG_NO IN (select values from v_catalog_nos_); 
END GET_PART_CHARACTERISTICS; 

回答

5

CatalogNos SQL類型(即未在包規範中聲明)?如果是這樣的:

PROCEDURE GET_PART_CHARACTERISTICS (v_catalog_nos_ IN CatalogNos, 
            Parts_Char_Cursor out sys_refcursor) 
AS 
BEGIN 
    OPEN Parts_Char_Cursor FOR 
    SELECT * FROM IFSAPP.SALES_PART_CHARACTERISTIC 
    WHERE CATALOG_NO IN (select * from table(v_catalog_nos_)); 
END GET_PART_CHARACTERISTICS; 

"This SQL gives an error: PLS-00642: local collection types not allowed in SQL statements"

所以CatalogNos不是SQL類型,即它是在一個封裝規格或機構宣稱PL/SQL類型。錯誤消息非常明確:我們不能在SQL語句中使用PL/SQL類型。就是那樣子。

最簡單的解決方案是使用SQL類型。

SQL> create or replace type CatalogNos is table of VARCHAR2(100);  
    2/

Type created. 

SQL> 

如果您真的不想創建自己的類型(爲什麼不?),您可以使用Oracle內置插件之一。就像這樣:

create or replace PROCEDURE GET_PART_CHARACTERISTICS 
     (v_catalog_nos_ IN sys.dbms_debug_vc2coll, 
     Parts_Char_Cursor out sys_refcursor) 
AS 
BEGIN 
    OPEN Parts_Char_Cursor FOR 
    SELECT * FROM IFSAPP.SALES_PART_CHARACTERISTIC 
    WHERE CATALOG_NO IN (select * from table(v_catalog_nos_)); 
END GET_PART_CHARACTERISTICS; 
/
+0

此SQL提供了一個錯誤:PLS-00642:SQL語句中不允許使用本地集合類型 – Adam 2011-12-28 21:41:35

0

使用||對於與可變

像拼接查詢:

type CatalogNos is table of VARCHAR2(100); 
PROCEDURE GET_PART_CHARACTERISTICS (v_catalog_nos_ IN CatalogNos, 
           Parts_Char_Cursor out sys_refcursor) AS 
BEGIN 
    OPEN Parts_Char_Cursor FOR 
    'SELECT * FROM IFSAPP.SALES_PART_CHARACTERISTIC 
    WHERE CATALOG_NO IN (select values from' || v_catalog_nos_ || ')'; 
END GET_PART_CHARACTERISTICS; 
+0

我仍然得到編譯錯誤... ORA-00936:缺少表達式,它指向「價值」的開始。 – Adam 2011-12-28 20:15:56

+2

'&'僅用於客戶端的SQL * Plus定義(交互)參數。這在存儲過程內的運行時不起作用。 – 2011-12-28 20:17:15

+0

你真的嘗試過嗎?如果不使用'table'函數,Oracle不能引用用戶定義的表類型。此建議的解決方案將無法工作。另外,即使它能夠工作,將變量的值連接成DML語句也是非常糟糕的做法。 – Allan 2011-12-29 16:25:27

2
create type CatalogNos is table of VARCHAR2(100); 

CREATE OR REPLACE PACKAGE your_package as 
    PROCEDURE GET_PART_CHARACTERISTICS (v_catalog_nos_ IN CatalogNos, 
             Parts_Char_Cursor out sys_refcursor); 
END your_package; 

CREATE OR REPLACE PACKAGE BODY your_package as 
    PROCEDURE GET_PART_CHARACTERISTICS (v_catalog_nos_ IN CatalogNos, 
             Parts_Char_Cursor out sys_refcursor) AS 
    BEGIN 
     OPEN Parts_Char_Cursor FOR 
     SELECT * FROM IFSAPP.SALES_PART_CHARACTERISTIC 
     WHERE CATALOG_NO IN (select column_value from table(v_catalog_nos_)); 
    END GET_PART_CHARACTERISTICS; 
END your_package; 

類型定義必須是一個數據庫對象,而不是包的一部分,爲了在SQL中使用。一旦這是真的,您可以使用table函數在from子句中引用該類型的變量。


基礎上的評論,看來我需要再次重申:爲了引用SQL用戶定義的數據類型,你必須定義包之外的類型作爲一個單獨的對象。


對於包含一個未命名字段一個用戶定義的表,可以使用任一或select *select column_value

+0

如果你的第一行在我的包定義中,那麼這個包就不會編譯。 – Adam 2011-12-28 21:10:16

+0

創建或替換包裝** BODY ** – 2011-12-29 07:08:49

+0

好吧,除「IN」語句中的values關鍵字之外,這一切都有效。它編譯,如果我用*替換它。 – Adam 2011-12-29 17:20:27