2010-01-11 22 views
8

Simplement en essayant de récupérer un curseur pour les identifiants que je spécifie.L'utilisation d'un type de table Oracle dans la clause IN - compile échoue

 
CREATE OR REPLACE PACKAGE some_package AS 

    TYPE t_cursor IS REF CURSOR; 
    TYPE t_id_table IS TABLE OF NVARCHAR(38) INDEX BY PLS_INTEGER; 

    PROCEDURE someentity_select(
    p_ids  IN t_id_table, 
    p_results OUT t_cursor); 

END; 

CREATE OR REPLACE PACKAGE BODY some_package AS 

    PROCEDURE someentity_select(
    p_ids  IN t_guid_table, 
    p_results OUT t_cursor) 
    IS 
    BEGIN 

    OPEN p_results FOR 
     SELECT * 
     FROM someschema.someentity 
     WHERE id IN (SELECT column_value FROM TABLE(p_ids)); - fails here 

    END; 

END; 

Note: someschema.someentity.id est un NVARCHAR2 (38)

PL/SQL: ORA-00382: l'expression est de type incorrect
PL/SQL: ORA-22905: ne peut pas accéder à des lignes à partir d'un élément de table non imbriqué

Où est-ce que je me trompe?

Répondre

10

Vous ne pouvez sélectionner à partir d'un type de collection qui est définie dans la base de données via une instruction CREATE TYPE, pas un tableau associatif:

CREATE TYPE t_id_table IS TABLE OF NVARCHAR(38); 

CREATE OR REPLACE PACKAGE some_package AS 

    PROCEDURE someentity_select(
    p_ids  IN t_guid_table, 
    p_results OUT SYS_REFCURSOR); 

END; 

CREATE OR REPLACE PACKAGE BODY some_package AS 

    PROCEDURE someentity_select(
    p_ids  IN t_guid_table, 
    p_results OUT SYS_REFCURSOR) 
    IS 
    BEGIN 

    OPEN p_results FOR 
     SELECT * 
     FROM someschema.someentity 
     WHERE id IN (SELECT column_value FROM TABLE(p_ids)); 

    END; 

END; 
+0

Merci .. mais maintenant il montre ORA-12714: jeu de caractères national invalide spécifié sur cette ligne .. beaucoup plus proche si. –

+1

Vous voudrez peut-être poster une autre question à ce sujet, car c'est un problème totalement différent et je n'ai aucune idée des problèmes de jeu de caractères nationaux. –

3

Ceci est un index par table, qui est un PL/Type SQL.

Vous pouvez uniquement utiliser des types SQL dans le moteur SQL d'Oracle. Ou types PL/SQL, qu'Oracle peut pirater pour ressembler à des types SQL.

Vous pouvez avoir une simple collection de type tableau et l'utiliser comme résultat. (Pas d'index par)

type TGuidList is table of NVarchar(38); 

Mais la meilleure compatibilité et de stabilité, vous obtenez en le déclarant comme un type global SQL et l'utiliser dans votre forfait:

créer un type TGuidList est table des nVarChar (38) ;

Editer: Vous n'aurez pas besoin d'un NVarChar pour un GUID, n'est-ce pas? Un bon vieux VarChar devrait bien faire l'affaire.

+0

Je dois utiliser NVarchar2 - cela fait partie de la base de données archaïque de mon client (ce qui explique aussi pourquoi j'utilise des SP). –