2013-01-09 5 views
1

Je dois faire un curseur qui reçoit une liste en tant que paramètre. Je l'ai essayé ceci:Type de collection en tant que paramètre de curseur

declare 

type array_t is table of varchar(50); -- //also tried varray(10) instead of table 

cursor c_cursor (p_list array_t) is 
select 
    field_1 
from 
    table_1 
where 
    field_2 in p_list; 

a_list array_t; 

begin 
    a_list := array_t('aaa', 
     'bbb', 
     'cccc', 
     'ddd'); 

    for v_cursor in c_cursor(a_list) loop 
     dbms_output.put_line(v_cursor.field_1); 
    end loop; 
end; 

et je reçois l'erreur suivante

ORA-06550: line 11, column 21: 
PLS-00642: local collection types not allowed in SQL statements 

J'ai lu sur l'utilisation de la méthode CREATE OR REPLACE mais je ne peux pas utiliser CREATE OR REPLACE dans ce cas (en fait la base de données est en lecture seule).

Y a-t-il une solution possible?

+0

S'il vous plaît ajouter la sortie attendue de la requête. – TechDo

+0

Voici quelques exemple: http://stackoverflow.com/questions/4249010/in-pl-sql-take-a-table-as-parameter-filter-it-and-return-it – Art

Répondre

0

vous avez besoin d'un type SQL et non d'un pl/sql, puis utilisez la syntaxe table pour l'utiliser.

que vous dites que vous ne pouvez pas créer un, essayez le construit en un sur DBMS_OUTPUT.

SQL> create table table_1(field_1 varchar2(20), field_2 varchar2(20)); 

Table created. 

SQL> insert into table_1 values ('test', 'aaa'); 

1 row created. 

SQL> insert into table_1 values ('test2', 'cccc'); 

1 row created. 

SQL> insert into table_1 values ('test3', 'x'); 

1 row created. 

SQL> commit; 

Commit complete. 

SQL> set serverout on 
SQL> declare 
    2 cursor c_cursor (p_list sys.DBMSOUTPUT_LINESARRAY) is 
    3 select /*+ cardinality(p, 10) */ 
    4  field_1 
    5 from 
    6  table_1 t 
    7  inner join table(p_list) p 
    8    on t.field_2 = p.column_value; 
    9 
10 a_list sys.DBMSOUTPUT_LINESARRAY; 
11 
12 begin 
13  a_list := sys.DBMSOUTPUT_LINESARRAY('aaa', 
14   'bbb', 
15   'cccc', 
16   'ddd'); 
17 
18  for v_cursor in c_cursor(a_list) loop 
19   dbms_output.put_line(v_cursor.field_1); 
20  end loop; 
21 end; 
22/
test 
test2 

l'indice /*+ cardinality(p, 10) */ est de dire Oracle à peu près le nombre de lignes seront dans le tableau. mettre un nombre représentatif, ou oracle supposera que le tableau contient @ 8k lignes qui peuvent causer un mauvais plan.

+0

PLS-00201: sys d'identification. DBMSOUTPUT_LINESARRAY doit être déclaré :( – Enrique

+0

@ user1961089 quelle version d'oracle êtes-vous? Vous devriez pouvoir utiliser un type approprié que vous voyez avec 'select owner, type_name, coll_type, elem_type_name, upper_bound, longueur de all_coll_types où elem_type_name = 'VARCHAR2' ' – DazzaL

+0

J'ai trouvé un type approprié, merci beaucoup. – Enrique

1

Vous devez créer le type séparément en utilisant la requête

CREATE OR REPLACE type array_t as table of varchar2(50); 

S'il vous plaît essayer après.

0

Cela peut aider - Oracle PL/SQL:

DECLARE 
    Type t_EmpNoArr IS VARRAY(20000) OF NUMBER(10) ; 
    v_RetVal t_EmpNoArr:= t_EmpNoArr(); 
    -- 
    FUNCTION retArray return t_EmpNoArr 
    IS 
    v_empnoArr t_EmpNoArr:= t_EmpNoArr(); 
    BEGIN 
    FOR i IN (SELECT empno FROM scott.emp) 
    LOOP 
     v_empnoArr.extend() ; 
     v_empnoArr(v_empnoArr.count):= i.empno ; 
    END LOOP; 
    -- 
    FOR j IN 1..v_empnoArr.COUNT() LOOP 
     DBMS_OUTPUT.PUT_LINE(v_empnoArr(j)); 
    END LOOP; 
    -- 
    RETURN v_empnoArr; 
END retArray; 
-- 
BEGIN 
    v_RetVal:= retArray(); 
END; 
/
Questions connexes