2017-08-09 3 views
3

J'ai défini le type d'enregistrement, le type de table et la fonction dans la spécification de paquet.Impossible de renvoyer le type de table à partir d'une fonction PLSQL

TYPE name_RECORD IS RECORD (
name VARCHAR2(244), 
surname VARCHAR2(244)); 

TYPE name_TABLE IS TABLE OF name_RECORD; 

function f_deps 
    (i_id_dept IN employees.id_department%type) 
    return name_TABLE; 

Et a écrit la fonction qui retourne le type de table dans le corps du paquet.

function f_deps 
    (i_id_dept IN employees.id_department%type) 
    return name_TABLE is 

CURSOR c1 IS (select * from employees); 
t_name name_TABLE; 
rec_name name_RECORD; 

BEGIN 
t_name := name_TABLE(); 
for i in c1 
LOOP 

    select name, surname BULK COLLECT INTO t_name from employees where id_department = i_id_dept ;    

END LOOP; 

return t_name; 

END f_deps; 

Fonction compile normal, mais lorsque je tente d'exécuter la fonction comme ceci:

select * from table(PACKAGE_employees.f_deps ('6')) ; 

je reçois cette erreur:

ORA-00902: invalid datatype 
00902. 00000 - "invalid datatype" 
*Cause:  
*Action: 
Error at Line: 29 Column: 22 

MISE À JOUR: J'ai défini les types avec instruction CREATE TYPE en ligne de commande, comme ce que Bob Jarvis a suggéré, mais je reçois toujours le même message d'erreur

create or replace type name_RECORD as object (
name VARCHAR2(244), 
surname VARCHAR2(244)); 

create or replace type name_TABLE AS TABLE OF name_RECORD; 
+0

Les types créés dans des packages ne peuvent pas être utilisés dans les instructions SELECT. Les instructions SELECT ne peuvent utiliser que les types créés à l'aide de CREATE TYPE. Bonne chance. –

+0

OK, merci pour la réponse. – Tom

+1

Ce n'est pas le cas en 12C - mais les types doivent être définis dans le package ** spécification ** pas de corps. Mais je pense seulement à l'intérieur de PL/SQL, pas à partir de la ligne de commande. –

Répondre

1

Il semble que vous ne pouvez pas sélectionner à l'aide de la fonction directement dans le SQL comme ceci:

select * from table(PACKAGE_employees.f_deps ('6')) ; 

Mais vous pouvez faire ceci:

declare 
    coll package_employees.name_table; 
begin 
    coll := package_employees.f_deps ('6'); 
    for r in (select * from table(coll)) loop 
    dbms_output.put_line(r.name); 
    end loop; 
end; 

Votre code de fonction ne va pas bien, il devrait être plus comme ceci:

function f_deps 
    (i_id_dept IN integer) 
    return name_TABLE is 
t_name name_TABLE; 
rec_name name_RECORD; 

BEGIN 

    select name_record(name, surname) 
    BULK COLLECT INTO t_name 
    from employees where id_department = i_id_dept ;    

return t_name; 

END f_deps; 

-à-dire

  • Aucun curseur et boucle nécessaire
  • Vous devez construire une valeur de type name_record en vrac recueillir dans une collection de name_record.
+0

OK, merci pour la réponse. Mais il y a un moyen de voir le type de table de la fonction dans un résultat de requête comme une table normale de la base de données? – Tom

+0

Oui - mais le code de votre fonction est erroné. Voir ma réponse mise à jour. –

+0

J'ai fait les modifications au code, mais quand je le compile, je reçois un message d'erreur: Erreur (195,4): PL/SQL: ORA-00913: trop de valeurs – Tom