El uso de un tipo de tabla de Oracle en la cláusula IN-- compilador falla
-
20-09-2019 - |
Pregunta
simplemente tratando de obtener un cursor de vuelta para los identificadores que especifique.
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;
Nota: someschema.someentity.id es un NVARCHAR2 (38)
PL / SQL: ORA-00382: la expresión es de tipo incorrecto
PL / SQL: ORA-22905: no se puede acceder a las filas de un elemento de la tabla no anidada
A dónde voy mal?
Solución
En las versiones de Oracle antes de 12.2 sólo se puede seleccionar de una colección tipo que se define en la base de datos a través de una sentencia CREATE TYPE, no una matriz asociativa:
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;
Otros consejos
Esta es una tabla de índices-by, que es un tipo PL / SQL.
Sólo puede utilizar los tipos de SQL en el motor SQL de Oracle. O tipos de PL / SQL, Oracle que puede cortar alrededor para que parezca tipos SQL.
Usted puede tener una simple colección tipo array y utilizarlo como consecuencia de ello. (Sin índice)
type TGuidList is table of NVarchar(38);
Sin embargo, la mejor compatibilidad y estabilidad, se obtiene por la que se declara como un tipo SQL mundial y el uso que dentro de su paquete:
crear tipo TGuidList es mesa de NVarchar (38);
Editar: Usted no necesitará un Nvarchar para un GUID, ¿verdad? Un buen ol' VarChar debe hacer el truco muy bien.