2010-05-21 91 views
26

我試圖將(varchar)數據數組傳遞到Oracle過程。 Oracle過程會從SQL * Plus或從另一個PL/SQL程序,像這樣既可以稱爲:將一組數據作爲輸入參數傳遞給Oracle過程

BEGIN 
pr_perform_task('1','2','3','4'); 
END; 

pr_perform_task將讀取每個輸入參數和執行的任務。

我不確定我是如何實現這一目標的。我首先想到的是使用varray類型的輸入參數,但我得到Error: PLS-00201: identifier 'VARRAY' must be declared錯誤,當程序definiton看起來是這樣的:

CREATE OR REPLACE PROCEDURE PR_DELETE_RECORD_VARRAY(P_ID VARRAY) IS

總之,我怎麼能傳遞數據作爲一個數組,讓SP循環遍歷每個參數並執行任務?

我使用Oracle 10gR2作爲我的數據庫。

回答

39

這是做這件事:

SQL> set serveroutput on 
SQL> CREATE OR REPLACE TYPE MyType AS VARRAY(200) OF VARCHAR2(50); 
    2/

Type created 

SQL> CREATE OR REPLACE PROCEDURE testing (t_in MyType) IS 
    2 BEGIN 
    3 FOR i IN 1..t_in.count LOOP 
    4  dbms_output.put_line(t_in(i)); 
    5 END LOOP; 
    6 END; 
    7/

Procedure created 

SQL> DECLARE 
    2 v_t MyType; 
    3 BEGIN 
    4 v_t := MyType(); 
    5 v_t.EXTEND(10); 
    6 v_t(1) := 'this is a test'; 
    7 v_t(2) := 'A second test line'; 
    8 testing(v_t); 
    9 END; 
10/

this is a test 
A second test line 

要擴大我對@ DCP的答案評論,這裏是你如何可以實現提出有解決辦法,如果你想使用一個關聯數組:

SQL> CREATE OR REPLACE PACKAGE p IS 
    2 TYPE p_type IS TABLE OF VARCHAR2(50) INDEX BY BINARY_INTEGER; 
    3 
    4 PROCEDURE pp (inp p_type); 
    5 END p; 
    6/

Package created 
SQL> CREATE OR REPLACE PACKAGE BODY p IS 
    2 PROCEDURE pp (inp p_type) IS 
    3 BEGIN 
    4  FOR i IN 1..inp.count LOOP 
    5  dbms_output.put_line(inp(i)); 
    6  END LOOP; 
    7 END pp; 
    8 END p; 
    9/

Package body created 
SQL> DECLARE 
    2 v_t p.p_type; 
    3 BEGIN 
    4 v_t(1) := 'this is a test of p'; 
    5 v_t(2) := 'A second test line for p'; 
    6 p.pp(v_t); 
    7 END; 
    8/

this is a test of p 
A second test line for p 

PL/SQL procedure successfully completed 

SQL> 

該行業建立一個獨立的Oracle類型(不能是關聯數組)與要求定義一個可以被所有人看到的包,以便它所定義的TYPE可以被所有人使用。

+0

不錯回答。我想知道是否可以做你的第一個方法,但是對於't_in'中的元素數量是動態的(也就是說,每次調用'testing'都不同)?似乎需要至少硬編碼「MyType」的上限?不知何故可以解除這個限制嗎? – ggkmath 2012-08-26 01:02:49

+1

@ggkmath,數組的大小並不重要,但是當您創建或更改TYPE時,您必須聲明VARRAY上限。 – DCookie 2012-08-26 01:23:04

+0

是否有替代解決方案可以適應這種動態大小,也許沒有VARRAY?如果脫離主題,我可以開始一個新的線程。 – ggkmath 2012-08-26 03:34:33

6

如果類型的參數都是相同的(varchar2爲例),你可以有一個包這樣,這將做到以下幾點:

CREATE OR REPLACE PACKAGE testuser.test_pkg IS 

    TYPE assoc_array_varchar2_t IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER; 

    PROCEDURE your_proc(p_parm IN assoc_array_varchar2_t); 

END test_pkg; 

CREATE OR REPLACE PACKAGE BODY testuser.test_pkg IS 

    PROCEDURE your_proc(p_parm IN assoc_array_varchar2_t) AS 
    BEGIN 
     FOR i IN p_parm.first .. p_parm.last 
     LOOP 
     dbms_output.put_line(p_parm(i)); 
     END LOOP; 

    END; 

END test_pkg; 

然後調用它,你就需要設置陣列,並將它傳遞:

DECLARE 
    l_array testuser.test_pkg.assoc_array_varchar2_t; 
BEGIN 
    l_array(0) := 'hello'; 
    l_array(1) := 'there'; 

    testuser.test_pkg.your_proc(l_array); 
END; 
/
+0

您無法創建Oracle類型的關聯數組。唯一可行的方法是在包中定義類型並以此方式引用它。 – DCookie 2010-05-21 21:38:50

+0

@DCookie - 我的錯,謝謝你指出錯誤。我糾正了我的答案:)。 – dcp 2010-05-21 22:52:09

+0

它是否需要創建一個包? – 2015-11-04 15:54:14

相關問題