2013-06-10 11 views
7

Sto scrivendo una funzione e voglio avvolgerla con la funzione tabella in modo da poter utilizzare con query di selezione.La funzione tabella con raccolta cumulativa genera un tipo di dati non valido

Qui è la mia dichiarazione di tipo e le alcune linee delle mie funzioni

CREATE OR REPLACE PACKAGE TYPES 
    AS 
     TYPE CURSORTYPE IS REF CURSOR; 

     TYPE vbugsrec 
      IS 
      RECORD (
       bug_id  bugs.bug_id%TYPE, 
       facility bugs.facility%TYPE 
      ); 

      TYPE vbugstable 
      IS 
      TABLE OF vbugsrec 
       INDEX BY BINARY_INTEGER; 

    END; 


    /
    CREATE OR REPLACE PACKAGE BODY CustomQueries 
    AS 
     FUNCTION pendverifylist (myldapid IN userpass.ldapalias%TYPE, 
           maxrows IN PLS_INTEGER:= CustomQueries.maxrecords) 
      RETURN types.vbugstable 
     IS 
      datarows types.vbugstable; 
      var_useralias userpass.ldapalias%TYPE 
       := UPPER (pendverifylist.myldapid) ; 

     CURSOR pendverify_cur (
      cursor_var_alias   IN   userpass.ldapalias%TYPE, 
      cursor_var_mybugstatus IN   bugs.bug_status%TYPE, 
      cursor_var_wild   IN   qa_list.component%TYPE 
     ) 
      IS 
      SELECT buglist.bug_id, buglist.facility 
       FROM bugs buglist, 
         (SELECT qa.product, qa.component 
         FROM qa_list qa, userpass UP 
         WHERE qa.qa_id = UP.userid 
           AND UP.ldapalias = cursor_var_alias) plist 
       WHERE  buglist.bug_status = cursor_var_mybugstatus 
         AND buglist.smr_state IN (SELECT fs.finalstate 
                FROM finalstates fs) 
         AND buglist.facility = plist.product 
         AND (buglist.product LIKE plist.component 
          OR plist.component = cursor_var_wild); 

     BEGIN 

      OPEN pendverifylist.pendverify_cur (cursor_var_alias   => pendverifylist.var_useralias, 
               cursor_var_mybugstatus => CustomQueries.default_bugstatus, 
               cursor_var_wild   => CustomQueries.wildcard); 

      FETCH pendverifylist.pendverify_cur 
      BULK COLLECT INTO pendverifylist.datarows 
      LIMIT LEAST (GREATEST (0, pendverifylist.maxrows), 
          CustomQueries.MAXRECORDS); 

      CLOSE pendverifylist.pendverify_cur; 

      RETURN pendverifylist.datarows; 

     END pendverifylist; 

    END CustomQueries; 
    /

quando voglio usare la funzione TAVOLO come qui di seguito, ho error.ORA-00902: tipo di dati non validi

SELECT * FROM TABLE(CUSTOMQUERIES.PENDVERIFYLIST ('product', 50)); 

Qualcuno può per favore aiutare quello che sto facendo male qui?

Grazie in anticipo

+2

I tipi devono essere dichiarati a livello di schema, non all'interno del pacchetto, per poterli utilizzare in una query SQL. –

+0

Ok mi dispiace ragazzi, ho postato l'intera cosa com'è ora. – Jeevan

+0

@AlexPoole si prega di verificare la domanda ora. I tipi sono dichiarati a livello di schema – Jeevan

risposta

15

si sta cercando di utilizzare i tipi a livello di pacchetto in SQL pianura, che non è consentito. I tipi dichiarati nel pacchetto non sono visibili o validi al di fuori di PL/SQL (o anche in semplici istruzioni SQL all'interno di PL/SQL). Una versione ridotta di quello che stai facendo:

create or replace package types as 
    type my_rec_type is record (dummy dual.dummy%type); 
    type my_table_type is table of my_rec_type index by binary_integer; 
end types; 
/

create or replace package p42 as 
    function get_table return types.my_table_type; 
end p42; 
/

create or replace package body p42 as 
    function get_table return types.my_table_type is 
     my_table types.my_table_type; 
    begin 
     select * bulk collect into my_table from dual; 
     return my_table; 
    end get_table; 
end p42; 
/

select * from table(p42.get_table); 

SQL Error: ORA-00902: invalid datatype 

Anche all'interno del pacchetto, se si ha una procedura che ha cercato di utilizzare la funzione di tabella che sarebbe errore. Se è stato aggiunto:

procedure test_proc is 
    begin 
     for r in (select * from table(get_table)) loop 
      null; 
     end loop; 
    end test_proc; 

... la compilazione corpo del pacchetto fallirebbe con ORA-22905: cannot access rows from a non-nested table item.

è necessario dichiarare il tipo a livello di schema, non in un pacchetto, in modo da utilizzare lo SQL create type command:

create type my_obj_type is object (dummy varchar2(1)); 
/

create type my_table_type is table of my_obj_type; 
/

create or replace package p42 as 
    function get_table return my_table_type; 
end p42; 
/

create or replace package body p42 as 
    function get_table return my_table_type is 
     my_table my_table_type; 
    begin 
     select my_obj_type(dummy) bulk collect into my_table from dual; 
     return my_table; 
    end get_table; 
end p42; 
/

select * from table(p42.get_table); 

DUMMY 
----- 
X 
0

Grazie a Alex Poole. Questo è quello che ho finito con

CREATE OR REPLACE TYPE vbugsrec 
     IS 
     OBJECT (
      bug_id  NUMBER(9), 
      facility VARCHAR2(256) 
     ); 

CREATE OR REPLACE TYPE vbugstable 
     IS 
     TABLE OF vbugsrec; 
/
CREATE OR REPLACE PACKAGE BODY CustomQueries 
AS 
    FUNCTION pendverifylist (myldapid IN userpass.ldapalias%TYPE, 
          maxrows IN PLS_INTEGER:= CustomQueries.maxrecords) 
     RETURN vbugstable 
    IS 
     datarows vbugstable := vbugstable(); 

     var_useralias userpass.ldapalias%TYPE:= UPPER (pendverifylist.myldapid) ; 

     TYPE temp_rec IS RECORD (
          bug_id  bugs.bug_id%TYPE, 
          facility bugs.facility%TYPE 
         ); 

     TYPE temp_records 
     IS 
     TABLE OF temp_rec 
      INDEX BY BINARY_INTEGER; 

     temporary_records temp_records; 

    CURSOR pendverify_cur (
     cursor_var_alias   IN   userpass.ldapalias%TYPE, 
     cursor_var_mybugstatus IN   bugs.bug_status%TYPE, 
     cursor_var_wild   IN   qa_list.component%TYPE 
    ) 
     IS 
     SELECT buglist.bug_id, buglist.facility 
      FROM bugs buglist, 
        (SELECT qa.product, qa.component 
        FROM qa_list qa, userpass UP 
        WHERE qa.qa_id = UP.userid 
          AND UP.ldapalias = cursor_var_alias) plist 
      WHERE  buglist.bug_status = cursor_var_mybugstatus 
        AND buglist.smr_state IN (SELECT fs.finalstate 
               FROM finalstates fs) 
        AND buglist.facility = plist.product 
        AND (buglist.product LIKE plist.component 
         OR plist.component = cursor_var_wild); 

    BEGIN 

     OPEN pendverifylist.pendverify_cur (cursor_var_alias   => pendverifylist.var_useralias, 
              cursor_var_mybugstatus => CustomQueries.default_bugstatus, 
              cursor_var_wild   => CustomQueries.wildcard); 

     FETCH pendverifylist.pendverify_cur 
     BULK COLLECT INTO temporary_records 
     LIMIT LEAST (GREATEST (0, pendverifylist.maxrows), 
         CustomQueries.MAXRECORDS); 

     CLOSE pendverifylist.pendverify_cur; 

     IF temporary_records.COUNT <> 0 
     THEN 
      FOR rec_idx IN temporary_records.FIRST .. temporary_records.LAST 
      LOOP 
      datarows.EXTEND; 
      datarows (datarows.LAST) := 
       vbugsrec (temporary_records (rec_idx).bug_id, 
           temporary_records (rec_idx).facility); 
      END LOOP; 
     END IF; 

     RETURN pendverifylist.datarows; 

    END pendverifylist; 

END CustomQueries; 
/
4

In realtà non è necessario disporre di tipi a livello di schema. Tutto quello che devi fare è definire la funzione come PIPELINED.

-- DEFINITION IN PCKG HEADER 
create or replace PACKAGE "AAA" IS 

    TYPE t_record IS RECORD (
    aaa VARCHAR(20 CHAR), 
    bbb VARCHAR(50 CHAR), 
    ccc VARCHAR(10 CHAR) 
); 

    TYPE t_collection is table of t_record; 

    FUNCTION get_records(p_in1 DATE, p_in2 DATE) RETURN t_collection PIPELINED; 

END AAA; 

-- PCKG BODY 
create or replace PACKAGE BODY AAA AS 

FUNCTION get_records(p_in1 DATE, p_in2 DATE) RETURN t_collection PIPELINED AS 
    CURSOR k1 is SELECT aaa,bbb,ccc FROM table; 
BEGIN 
    FOR rec IN k1 
    LOOP 
    pipe row((rec)); 
    END LOOP;  
END get_records 
END AAA; 

-- CALLING FUNCTION OUTSIDE OF PCKG 
select * from TABLE(AAA.get_records(par1, par2)); 
Problemi correlati