2010-07-30 22 views
13

Quiero devolver filas desde una declaración de selección dentro de un bloque declare/begin/end. Puedo hacer esto en T-SQL, pero me gustaría saber cómo hacerlo en PL/SQL.¿Cómo devolver filas desde un bloque de declarar/comenzar/finalizar en Oracle?

El código es un poco como la siguiente:

declare 
    blah number := 42; 
begin 
    select * 
    from x 
    where x.value = blah; 
end; 
+0

No puede retu rn datos del bloque PLSQL anónimo. –

+0

sí, puede, por ejemplo, en 'node oracledb' utiliza' oracledb.BIND_OUT' check https://github.com/oracle/node-oracledb/blob/master/doc/api.md – Toolkit

Respuesta

10

Un bloque PL/SQL anónimos, como el que se ha mostrado, no puede "volver" nada. Sin embargo, puede interactuar con la persona que llama por medio de variables de vinculación.

Así que el método que utilizaría en este caso sería declarar una referencia de cursor, abrirla en el bloque PL/SQL para la consulta deseada, y dejar que la aplicación que llama extraiga las filas de ella. En SQLPlus esto se vería así:

variable rc refcursor 

declare 
    blah number := 42; 
begin 
    open :rc for 
    select * 
    from x 
    where x.value = blah; 
end; 
/

print x 

Si modifica su PL/SQL como una función almacenada, entonces podría devolver valores. En este caso lo que es posible que desee hacer es crear un tipo de colección, recupera todas las filas en una variable de ese tipo, y devolverlo:

CREATE TYPE number_table AS TABLE OF NUMBER; 

CREATE FUNCTION get_blah_from_x (blah INTEGER) 
    RETURN number_table 
    IS 
    values number_table; 
    BEGIN 
    SELECT id 
     BULK COLLECT INTO values 
     FROM x 
     WHERE x.value = blah; 
    RETURN values; 
    END; 
/
+0

Gracias - ¡buena respuesta! Sin embargo, ¿cuáles son las implicaciones de rendimiento de usar un cursor en este caso? Siempre trato de evitarlos por su mal desempeño en T-SQL. –

+1

Un cursor no es más que una referencia a un conjunto de resultados. La penalización de rendimiento proviene de los recorridos de ida y vuelta que están involucrados entre la obtención de cada registro. Sin embargo, cada selección que invoque contra Oracle le será devuelta en forma de cursor. En .Net se llaman DataReaders. Cuando no tienes problemas de rendimiento con ellos, no tendrás problemas de rendimiento con los cursores. –

0

Bueno, esto depende en gran medida de la biblioteca de acceso a datos.

Puede devolver cualquier tipo compatible con SQL como parámetro. Esto incluye tipos de SQL complejos y tipos de colección. Pero la mayoría de las bibliotecas simplemente no son capaces de manejar los tipos de objetos de Oracle.

De cualquier manera, mis ejemplos utilizarán estos tipos de objetos:

create type SomeType as object(Field1 VarChar(50)); 

create type SomeTypeList as table of SomeType; 

Cuando su biblioteca de acceso puede manejar los tipos de objetos, sólo podían devolver una lista de objetos PL/SQL:

begin 
    :list := SomeTypeList(SomeType('a'),SomeType('b'),SomeType('c')); 
end; 

Si no, puede hackearlo forzando esta lista en una selección y devolver su resultado como un cursor:

declare 
    list SomeTypeList; 
begin 
    list := SomeTypeList(SomeType('a'),SomeType('b'),SomeType('c')); 
    open :yourCursor for 
    SELECT A 
    FROM table(list); 
end; 
Cuestiones relacionadas