tutorial tipos salida resueltos procedimientos procedimiento parametros funciones example español ejemplos ejecutar con bloques almacenado sql oracle plsql oracle10g oracle-apex

tipos - ¿Es posible emitir un estado SELECT desde un bloque PL/SQL?



procedimientos y funciones oracle pl/sql (10)

¿Cómo puedo obtener un bloque PL / SQL para generar los resultados de una instrucción SELECT la misma manera que si hubiera hecho un SELECT simple?

Por ejemplo, cómo hacer un SELECT como:

SELECT foo, bar FROM foobar;

Insinuación :

BEGIN SELECT foo, bar FROM foobar; END;

no funciona


Crea una función en un paquete y devuelve un SYS_REFCURSOR:

FUNCTION Function1 return SYS_REFCURSOR IS l_cursor SYS_REFCURSOR; BEGIN open l_cursor for SELECT foo,bar FROM foobar; return l_cursor; END Function1;


Depende de para qué necesitas el resultado.

Si está seguro de que va a haber solo 1 fila, use el cursor implícito:

DECLARE v_foo foobar.foo%TYPE; v_bar foobar.bar%TYPE; BEGIN SELECT foo,bar FROM foobar INTO v_foo, v_bar; -- Print the foo and bar values dbms_output.put_line(''foo='' || v_foo || '', bar='' || v_bar); EXCEPTION WHEN NO_DATA_FOUND THEN -- No rows selected, insert your exception handler here WHEN TOO_MANY_ROWS THEN -- More than 1 row seleced, insert your exception handler here END;

Si desea seleccionar más de 1 fila, puede usar un cursor explícito:

DECLARE CURSOR cur_foobar IS SELECT foo, bar FROM foobar; v_foo foobar.foo%TYPE; v_bar foobar.bar%TYPE; BEGIN -- Open the cursor and loop through the records OPEN cur_foobar; LOOP FETCH cur_foobar INTO v_foo, v_bar; EXIT WHEN cur_foobar%NOTFOUND; -- Print the foo and bar values dbms_output.put_line(''foo='' || v_foo || '', bar='' || v_bar); END LOOP; CLOSE cur_foobar; END;

o usa otro tipo de cursor:

BEGIN -- Open the cursor and loop through the records FOR v_rec IN (SELECT foo, bar FROM foobar) LOOP -- Print the foo and bar values dbms_output.put_line(''foo='' || v_rec.foo || '', bar='' || v_rec.bar); END LOOP; END;


Desde un bloque anónimo? Me gustaría ahora más sobre la situación en la que piensas que es necesario, porque con las cláusulas de factorización de subconsulta y vistas en línea es bastante raro que necesites recurrir a PL / SQL para cualquier cosa que no sea la situación más compleja.

Si puede usar un procedimiento con nombre, entonces use funciones segmentadas. Aquí hay un ejemplo extraído de la documentación:

CREATE PACKAGE pkg1 AS TYPE numset_t IS TABLE OF NUMBER; FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED; END pkg1; / CREATE PACKAGE BODY pkg1 AS -- FUNCTION f1 returns a collection of elements (1,2,3,... x) FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED IS BEGIN FOR i IN 1..x LOOP PIPE ROW(i); END LOOP; RETURN; END; END pkg1; / -- pipelined function is used in FROM clause of SELECT statement SELECT * FROM TABLE(pkg1.f1(5));



Incluso si la pregunta es antigua, pero compartiré la solución que responde perfectamente a la pregunta:

SET SERVEROUTPUT ON; DECLARE RC SYS_REFCURSOR; Result1 varchar2(25); Result2 varchar2(25); BEGIN OPEN RC FOR SELECT foo, bar into Result1, Result2 FROM foobar; DBMS_SQL.RETURN_RESULT(RC); END;


Necesita usar SQL dinámico nativo. Además, no necesita BEGIN-END para ejecutar el comando SQL:

declare l_tabname VARCHAR2(100) := ''dual''; l_val1 VARCHAR2(100):= ''''''foo''''''; l_val2 VARCHAR2(100):= ''''''bar''''''; l_sql VARCHAR2(1000); begin l_sql:= ''SELECT ''||l_val1||'',''||l_val2||'' FROM ''||l_tabname; execute immediate l_sql; dbms_output.put_line(l_sql); end; / Output: SELECT ''foo'',''bar'' FROM dual


Para versiones inferiores a 12c, la respuesta simple es NO , al menos no en la forma en que se está haciendo es SQL Server.
Puede imprimir los resultados, puede insertar los resultados en tablas, puede devolver los resultados como cursores dentro de la función / procedimiento o devolver un conjunto de filas desde la función -
pero no puede ejecutar la instrucción SELECT, sin hacer algo con los resultados.

servidor SQL

begin select 1+1 select 2+2 select 3+3 end

/ * 3 conjuntos de resultados devueltos * /

Oráculo

SQL> begin 2 select 1+1 from dual; 3 end; 4 / select * from dual; * ERROR at line 2: ORA-06550: line 2, column 1: PLS-00428: an INTO clause is expected in this SELECT statement


Puede hacer esto en Oracle 12.1 o superior:

declare rc sys_refcursor; begin open rc for select * from dual; dbms_sql.return_result(rc); end;

No tengo una base de datos 12.x o DBVisualizer para probar, pero ese debería ser probablemente su punto de partida.

Para obtener más detalles, consulte Conjuntos de resultados implícitos en la Guía de nuevas características de Oracle 12.1 , Blog de Tom Kyte , Base de Oracle, etc.

Para versiones anteriores, dependiendo de la herramienta, es posible que pueda usar las variables de vinculación del cursor de ref. Como este ejemplo de SQL * Plus:

set autoprint on var rc refcursor begin open :rc for select count(*) from dual; end; / PL/SQL procedure successfully completed. COUNT(*) ---------- 1 1 row selected.


si desea ver la salida de selección de la consulta en pl / sql, necesita usar un cursor explícito. Que contendrá el conjunto de datos activo y, al buscar cada fila a la vez, mostrará todo el registro del conjunto de datos activo, siempre que recupere el registro del conjunto de datos al iterar en bucle. Esta información no se generará en formato tabular, este resultado será en formato de texto plano. Esperamos que esto sea útil. Para cualquier otra consulta, puede preguntar ....

set serveroutput on; declare cursor c1 is select foo, bar from foobar; begin for i in c1 loop dbms_output.put_line(i.foo || '' '' || i.bar); end loop; end;


utilizar ejecutar declaración inmediata

me gusta:

declare var1 integer; var2 varchar2(200) begin execute immediate ''select emp_id,emp_name from emp'' into var1,var2; dbms_output.put_line(var1 || var2); end;