2010-05-21 30 views
26

Tôi đang cố chuyển một mảng dữ liệu (varchar) vào quy trình Oracle. Thủ tục Oracle sẽ được hoặc là gọi từ SQL * Plus hoặc từ một thủ tục PL/SQL như sau:Truyền một mảng dữ liệu làm tham số đầu vào cho quy trình Oracle

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

pr_perform_task sẽ đọc mỗi của các thông số đầu vào và thực hiện nhiệm vụ.

Tôi không chắc chắn làm thế nào tôi có thể đạt được điều này. Suy nghĩ đầu tiên của tôi là sử dụng một tham số đầu vào của loại varray nhưng tôi nhận được Error: PLS-00201: identifier 'VARRAY' must be declared lỗi, khi definiton thủ tục trông như thế này:

CREATE OR REPLACE PROCEDURE PR_DELETE_RECORD_VARRAY(P_ID VARRAY) IS

Để tóm tắt, làm thế nào tôi có thể vượt qua các dữ liệu như một mảng, cho phép vòng lặp SP thông qua từng tham số và thực hiện tác vụ?

Tôi đang sử dụng Oracle 10gR2 làm cơ sở dữ liệu của mình.

Trả lời

39

Đây là một cách để làm điều đó:

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 

để mở rộng về nhận xét của tôi để trả lời @ DCP của, dưới đây là cách bạn có thể thực hiện các giải pháp đề xuất ở đó nếu bạn muốn sử dụng một mảng kết hợp:

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> 

này nghề tạo độc lập Oracle TYPE (mà không thể là một mảng kết hợp) với yêu cầu định nghĩa của một gói có thể được nhìn thấy bởi tất cả để TYPE nó định nghĩa có thể được sử dụng bởi tất cả.

+0

Đẹp câu trả lời. Tôi tự hỏi nếu nó có thể làm những gì phương pháp đầu tiên của bạn không, nhưng đối với tình huống mà số lượng các yếu tố trong 't_in' là năng động (có nghĩa là, nó khác nhau cho mỗi cuộc gọi để' thử nghiệm')? Nó có vẻ như một trong những nhu cầu để ít nhất là mã cứng một giới hạn trên cho 'MyType'? Giới hạn đó có thể được nâng lên bằng cách nào đó không? – ggkmath

+1

@ggkmath, dù mảng có lớn đến mức nào, nhưng bạn phải khai báo giới hạn trên VARRAY khi bạn tạo hoặc thay đổi TYPE. – DCookie

+0

Có giải pháp thay thế nào có thể chứa kích thước động như vậy, có lẽ không có VARRAY? Nếu tắt chủ đề, tôi có thể bắt đầu một chủ đề mới. – ggkmath

6

Nếu loại các thông số đều như nhau (varchar2 chẳng hạn), bạn có thể có một gói phần mềm như thế này mà sẽ làm như sau:

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; 

Sau đó, để gọi nó, bạn sẽ cần phải thiết lập mảng và vượt qua nó:

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

Bạn không thể tạo một loại Oracle của mảng kết hợp. Cách duy nhất có thể làm việc này là xác định loại trong một gói và tham chiếu nó theo cách đó. – DCookie

+0

@DCookie - Lỗi của tôi, cảm ơn vì đã chỉ ra sai lầm. Tôi đã sửa câu trả lời của tôi :). – dcp

+0

Is It có cần tạo một gói không? –

Các vấn đề liên quan