 |
|
 |
Cursores Explicitos en PL/SQL
Declaración de cursores explicitos
Los cursores explicitos se emplean para realizar consultas SELECT que pueden devolver cero filas, o más de una fila.
Para trabajar con un cursor explicito necesitamos realizar las siguientes tareas:
- Declarar el cursor.
- Abrir el cursor con la instrucción OPEN.
- Leer los datos del cursor con la instrucción FETCH.
- Cerrar el cursor y liberar los recursos con la instrucción CLOSE.
Para declarar un cursor debemos emplear la siguiente sintaxis:
CURSOR nombre_cursor IS
instrucción_SELECT
|
También debemos declarar los posibles parametros que requiera el cursor:
CURSOR nombre_cursor(param1 tipo1, ..., paramN tipoN) IS
instrucción_SELECT
|
Para abrir el cursor
OPEN nombre_cursor;
o bien (en el caso de un cursor con parámetros) OPEN nombre_cursor(valor1, valor2, ..., valorN); |
Para recuperar los datos en variables PL/SQL.
FETCH nombre_cursor INTO lista_variables; -- o bien ...
FETCH nombre_cursor INTO registro_PL/SQL;
|
Para cerrar el cursor:
El siguiente ejemplo ilustra el trabajo con un cursor explicito. Hay que tener en cuenta que al leer los datos del cursor debemos hacerlo sobre variables del mismo tipo de datos de la tabla (o tablas) que trata el cursor.
DECLARE CURSOR cpaises IS SELECT CO_PAIS, DESCRIPCION, CONTINENTE FROM PAISES;
co_pais VARCHAR2(3); descripcion VARCHAR2(50); continente VARCHAR2(25); BEGIN OPEN cpaises; FETCH cpaises INTO co_pais,descripcion,continente; CLOSE cpaises; END;
|
Podemos simplificar el ejemplo utilizando el atributo de tipo %ROWTYPE sobre el cursor.
DECLARE CURSOR cpaises IS SELECT CO_PAIS, DESCRIPCION, CONTINENTE FROM PAISES; registro cpaises%ROWTYPE; BEGIN OPEN cpaises; FETCH cpaises INTO registro; CLOSE cpaises; END;
|
El mismo ejemplo, pero utilizando parámetros:
DECLARE CURSOR cpaises (p_continente VARCHAR2) IS SELECT CO_PAIS, DESCRIPCION, CONTINENTE FROM PAISES WHERE CONTINENTE = p_continente; registro cpaises%ROWTYPE; BEGIN OPEN cpaises('EUROPA'); FETCH cpaises INTO registro; CLOSE cpaises; END;
|
Cuando trabajamos con cursores debemos considerar:
- Cuando un cursor está cerrado, no se puede leer.
- Cuando leemos un cursor debemos comprobar el resultado de la lectura utilizando los atributos de los cursores.
- Cuando se cierra el cursor, es ilegal tratar de usarlo.
- Es ilegal tratar de cerrar un cursor que ya está cerrado o no ha sido abierto
Atributos de cursores Toman los valores TRUE, FALSE o NULL dependiendo de la situación:
| Atributo | Antes de abrir | Al abrir | Durante la recuperación | Al finalizar la recuperación | Después de cerrar |
|---|
| %NOTFOUND | ORA-1001 | NULL | FALSE | TRUE | ORA-1001 | | %FOUND | ORA-1001 | NULL | TRUE | FALSE | ORA-1001 | | %ISOPEN | FALSE | TRUE | TRUE | TRUE | FALSE | | %ROWCOUNT | ORA-1001 | 0 | * | ** | ORA-1001 |
* Número de registros que ha recuperado hasta el momento ** Número de total de registros
Manejo del cursor
Por medio de ciclo LOOP podemos iterar a través del cursor. Debe tenerse cuidado de agregar una condición para salir del bucle:
Vamos a ver varias formas de iterar a través de un cursor. La primera es utilizando un bucle LOOP con una sentencia EXIT condicionada:
OPEN nombre_cursor;
LOOP
FETCH nombre_cursor INTO lista_variables;
EXIT WHEN nombre_cursor%NOTFOUND;
/* Procesamiento de los registros recuperados */
END LOOP;
CLOSE nombre_cursor;
|
Aplicada a nuestro ejemplo anterior:
DECLARE
CURSOR cpaises IS SELECT CO_PAIS, DESCRIPCION, CONTINENTE FROM PAISES; co_pais VARCHAR2(3); descripcion VARCHAR2(50); continente VARCHAR2(25); BEGIN OPEN cpaises; LOOP FETCH cpaises INTO co_pais,descripcion,continente; EXIT WHEN cpaises%NOTFOUND; dbms_output.put_line(descripcion); END LOOP; CLOSE cpaises; END;
|
Otra forma es por medio de un bucle WHILE LOOP. La instrucción FECTH aparece dos veces.
OPEN nombre_cursor;
FETCH nombre_cursor INTO lista_variables;
WHILE nombre_cursor%FOUND LOOP
/* Procesamiento de los registros recuperados */
FETCH nombre_cursor INTO lista_variables;
END LOOP;
CLOSE nombre_cursor; |
DECLARE CURSOR cpaises IS SELECT CO_PAIS, DESCRIPCION, CONTINENTE FROM PAISES; co_pais VARCHAR2(3); descripcion VARCHAR2(50); continente VARCHAR2(25); BEGIN OPEN cpaises; FETCH cpaises INTO co_pais,descripcion,continente; WHILE cpaises%found LOOP dbms_output.put_line(descripcion); FETCH cpaises INTO co_pais,descripcion,continente; END LOOP; CLOSE cpaises; END;
|
Por último podemos usar un bucle FOR LOOP. Es la forma más corta ya que el cursor es implicitamente se ejecutan las instrucciones OPEN, FECTH y CLOSE.
FOR variable IN nombre_cursor LOOP
/* Procesamiento de los registros recuperados */
END LOOP;
|
BEGIN FOR REG IN (SELECT * FROM PAISES) LOOP dbms_output.put_line(reg.descripcion); END LOOP; END;
|
|
| |
 |
Felicitaciones
por
Maggie
Respuesta recibida el [27/06/2007 12:05:23]
|
 |
Muchas felicitaciones por tu sitio, es genial, sigue adelante por favor.
|
| |
 |
g
por
anonimo
Respuesta recibida el [06/08/2007 05:48:10]
|
 |
very good man
|
| |
 |
HOLa
por
ALEX
Respuesta recibida el [21/09/2007 02:32:52]
|
 |
acabo de isntalar sql y ya cree dos usuarios pero cuando quiero conectarme es decir poner el comando connect me manda error no se que estoy haciendo mal??'
|
| |
 |
excelente
por
rmartinez
Respuesta recibida el [22/09/2007 09:34:21]
|
 |
Excelente Curso!!
|
| |
 |
Perfecto!
por
OsKr
Respuesta recibida el [27/11/2007 07:58:38]
|
 |
La página está increible, es muy clara y completa. Gracias x compartir tu conocimiento Pedro!
|
| |
 |
consulta
por
valeria
Respuesta recibida el [05/12/2007 06:22:03]
|
 |
Es muy claro lo que ecplican pero me queda una duda: cuando se cargan los datos en el cursor, al hacer el open o al hacer el fetch?? en otras palabras quiero saber en que momento tengo que formatear las variables auxiliares que tengo en los campos del where. Gracias
|
| |
 |
Listas de Valores
por
ellerysammy
Respuesta recibida el [18/12/2007 02:28:47]
|
 |
Estoy trabajando con Form de Oracle te queria preguntar si esta a tu alcanze decirme si es pocsible llenar una LOV(Lista de Valores) con los datos extraidos en un cursor o en un arreglo, he estado intentando pero no me sale, te agradeceria me ayudaras
|
| |
 |
re: consulta por valeria
por
Martín
Respuesta recibida el [02/01/2008 12:02:23]
|
 |
Valeria, los datos se cargan en el cursor cuando lo definis. cursor nombre_cursor is select col1, col2 from tabla_1 ahí. Y si lo cargas en una variable, parece que es con fetch nombre_cursor into variables ... saludos
|
| |
 |
Excelente!!!
por
Tincho
Respuesta recibida el [26/02/2008 09:12:16]
|
 |
La verdad que tus cursos estan muy bien diseñados... hay que saber trasmitir... y la verdad que eso se evidencia en el tuto. Gracias!!! por no ser mesquino. bay
|
| |
 |
excelente pero bue...
por
matanga
Respuesta recibida el [26/02/2008 09:16:36]
|
 |
la verdad es que a tincho lo tengo al lado haciendo una capacitacion y no entiende nada, pero el curso esta muy bueno, me pregunta todo lo que lee
|
| |
 |
excelente
por
chuchu
Respuesta recibida el [26/02/2008 12:17:31]
|
 |
excelente el tutorail, me sirvio de mucho
|
| |
 |
EXCELENTE
por
ZULMISSS
Respuesta recibida el [28/02/2008 08:00:04]
|
 |
FELICITACIONES TRABAJAMOS EN BASE A ESTE TUTORIAL INFINITAS GRACIAS
|
| |
 |
Buenisimo
por
HLE
Respuesta recibida el [05/03/2008 02:47:53]
|
 |
Excelente manual, siempre lo utilizo como referencia, que bueno que algo de esta calidad se pueda encontrar gratis en la red.
|
| |
 |
Presiso
por
Dj_kamus
Respuesta recibida el [03/04/2008 01:45:43]
|
 |
esta super bien explicado, muchas gracias
|
| |
 |
excelebte
por
zague
Respuesta recibida el [13/04/2008 09:51:12]
|
 |
Me esta sirvendo mucho te lo agradesco de verdad ESTA MUY BIEN TRABAJADO FELICIDADES
|
| |
 |
GRACIAS!!!
por
ALVRZ!
Respuesta recibida el [15/04/2008 01:56:37]
|
 |
e estado todo el día estudiando PL/SQL, y solo e logrado comprender leyendo de tu sitio! muchas gracias man sigue asi!
WOOOOW!
|
| |
 |
cursor bucle FOR...IN..LOOP
por
nuno
Respuesta recibida el [29/05/2008 03:39:09]
|
 |
Hola,
Mi pregunta es si uso un cursor con bucle FOR...IN..LOOP para updatear un campo del select de ese mismo curosr, lo cierro con END LOOP y lo vuelvo a abrir con FOR...IN..LOOP, se veran los cambios de dicha actualizacio en la nueva select dentro del nuevo bucle?
Gracias en adelanto,
nuno
|
| |
 |
hola tienes un buen tutorial p...
por
Anónimo
Respuesta recibida el [07/08/2008 04:51:11]
|
 |
hola tienes un buen tutorial pero es que no se como utilizar esta instruccion imagine que me imprimia de una vez, pero solo me sale procedimiento terminado correctamente no se como imprimir luego dbms_output.put_line(reg.descripcion);
|
| |
 |
me salvaste la vida!!!
por
Mary
Respuesta recibida el [21/08/2008 08:59:22]
|
 |
Gracias, gracias, muchisimas gracias esta página acaba de resucitar a un muerto
|
| |
 |
Ahorrando
por
NLeivaS
Respuesta recibida el [27/08/2008 11:25:04]
|
 |
Gracias por tus ejemplos, me sirvieron de mucho en un principio.
Copio ejemplo que encontré en otras páginas, lo agrego ya que vi que tu ejemplo en este caso está al final y muy escueto, siendo el mas flexible y fácil de programar (FOR LOOP):
DECLARE CURSOR occupancy_cur IS SELECT pet_id, room_number FROM occupancy WHERE occupied_dt = SYSDATE; BEGIN FOR occupancy_rec IN occupancy_cur LOOP update_bill (occupancy_rec.pet_id, occupancy_rec.room_number); END LOOP; END;
No necesitas OPEN, FETCH, CLOSE, %FOUND
Here you see the beautiful simplicity of the cursor FOR loop! Gone is the declaration of the record. Gone are the OPEN, FETCH, and CLOSE statements. Gone is the need to check the %FOUND attribute. Gone are the worries of getting everything right. Instead, you say to PL/SQL, in effect, "You and I both know that I want each row and I want to dump that row into a record that matches the cursor. Take care of that for me, will you?" And PL/SQL does take care of it, just the way any modern programming language should.
|
| |
 |
Gracias
por
Jair
Respuesta recibida el [21/09/2008 07:13:26]
|
 |
Hola, agradecerte por este curso de pl sql anteriormente me habia bajado un manual en pdf que no se entendia nada, y con este curso estoy entiendo mucho pero mucho mas facil, muchas gracias y sigue adelante :)
|
| |
 |
Muy buen Tutorial
por
Scard
Respuesta recibida el [16/10/2008 04:02:33]
|
 |
Bastante digerible y mas que ando aprendiendo de pronto PL por exigencias de trabajo EXCELENTE TRABAJO
|
| |
 |
Y si quiero imprimir lo que el cursor tiene
por
Marino
Respuesta recibida el [07/11/2008 09:16:16]
|
 |
Yo veo que en el ejemplo se muestra o se imprime un campo de todo el cursor. Pero si quiero que me imprima todo lo que el cursos tenga? Por ejemplo: si mi cursos optiene los campos, COD, NOMBRE, TELEFONO Ustedes imprimen solo el nombre dbms_output.put_line(NOMBRE); pero si quiero que imprima todo los campos?, como se realiza? dbms_output.put_line(COD,NOMBRE,TELEFONO);
Esta bien esto? o como se debe de realizar.
Gracias
|
| |
 |
Para Marino
por
Saul Hudson
Respuesta recibida el [18/12/2008 11:08:01]
|
 |
Debes concatenar los valores o campos asi:
dbms_output.put_line(COD||NOMBRE||TELEFONO);
|
| |
 |
Excelente sitio.
por
LuisALO
Respuesta recibida el [30/12/2008 12:03:43]
|
 |
Muchas gracias Pedro por aportar tus conocimientos y compartir este sitio, todo esta muy claro y servicial y en lo personal me ha servido mucho este sitio. Feliz Año nuevo a todos los colegas informaticos que andan por aqui!!
|
| |
 |
Gracias
por
Elizabeth
Respuesta recibida el [27/01/2009 10:33:41]
|
 |
Gracias por esta publicacion me sirvio para aclarar algunas dudas que tenia sobre el manejo de cursores..
|
| |
 |
Ayuda con Cursor
por
Fernando
Respuesta recibida el [28/01/2009 05:41:55]
|
 |
Buenas Tardes, soy nuevo en esto del Oracle y tengo el siguiente problema, tengo un procedimiento que recibe parametros de entrada, como podria declarar el cursor ya que he intentado de varias formas y me marca error???
|
| |
 |
Gracias
por
Daiana
Respuesta recibida el [03/02/2009 11:36:07]
|
 |
Gracias, el texto me ha ayudado mucho.
|
| |
 |
for
por
luis
Respuesta recibida el [09/07/2009 09:32:19]
|
 |
con este ejemplo de como se ocuparia el for que no me quedo muy claro DECLARE CURSOR cpaises IS SELECT CO_PAIS, DESCRIPCION, CONTINENTE FROM PAISES; co_pais VARCHAR2 (3); descripcion VARCHAR2 (50); continente VARCHAR2 (25);
|
| |
 |
este for esta bien
por
luis
Respuesta recibida el [09/07/2009 09:40:08]
|
 |
este for esta bien hecho DECLARE CURSOR cpaises IS SELECT CO_PAIS, DESCRIPCION, CONTINENTE FROM PAISES; registro cpaises%ROWTYPE; BEGIN FOR registro REG IN cpaises LOOP dbms_output.put_line(registro.descripcion); END LOOP; END;
|
| |
 |
Pocas palabras, mucha explicación
por
xuser83
Respuesta recibida el [19/08/2009 10:43:35]
|
 |
Pocas palabras, mucha explicación
|
| |
 |
La caña
por
Bogey
Respuesta recibida el [24/11/2009 12:25:27]
|
 |
He mirado varios tutoriales de esta página, y la verdad, están hechos como si fueran para "tontos", sin ánimos de ofender a nadie, yo me incluyo como primer tonto, ya que está todo super bien explicado y super claro, y ayuda mogollón a gente como yo, que aunque lo entendamos a la primera siempre nos quedan algunas dudas.
|
| |
 |
Salir del bucle antes de que acabe
por
Natalia
Respuesta recibida el [03/12/2009 04:58:56]
|
 |
Hola, muchas gracias por estas explicaciones. Tengo una pregunta, si tengo un FOR a IN c_a LOOP Y una condicion que termina el bucle antes de tiempo, el cursor se cierra o se queda abierto y tengo que cerrarlo explicitamente? He visto que se puede comprobar con: IF c_a%isopen then ... pero no se si necesito hacerlo o no.
|
| |
 |
PARA NATALIA:
si te sales del...
por
ingeniero_aprendiz
Respuesta recibida el [12/01/2010 03:56:36]
|
 |
PARA NATALIA: si te sales del loop no lleva explicito que te salgas debido a que no tenga mas datos. Para salirte del cursor para que no haya mas datos EXIT WHEN CURSO%NOTFOUND , eso si, si has echo el OPEN del cursor , el FETCH y esas cosas. Si has ido por el camino rapido, directamente el for, ANTES DE QUE EL BUCLE CONTINUE, IMPLICITAMENTE SE CHEQUEA QUE HAYA DATOS EN EL CURSOR. no se si te he respondido mas o menos
|
| Añadir comentario ... |
Para preguntar utiliza los foros
|
|

|
Cursores Explicitos en PL/SQL |
|
Autor:
Pedro Herrarte Sánchez
|
|
Visitas:
141621 |
Fecha de publicación:
24/05/2006 |
Pedro Herrarte, es consultor independiente, ofreciendo servicios de consultoría, análisis, desarrollo y formación.
Posee mas de diez años de experiencia trabajando para las principales empresas de España.
Es especialista en tecnologías .NET, entornos Web, bases de datos (SQL Server y ORACLE) e integración de sistemas.
Es experto en desarrollo (C#, ASP.NET, VB.Net, T-SQL, PL/SQL, , ASP, CGI , C, Pro*C, Java, Essbase, Vignette, PowerBuilder y Visual Basic ...) y bases de datos (SQL Server y ORACLE).
Es fundador, diseñador y programador de www.devjoker.com. |
|
|
Visitas:
109
|
Comentarios:
3
|
Archivo:
Articulos
|
Visitas:
809
|
Comentarios:
2
|
Archivo:
Articulos
|
Visitas:
764
|
Comentarios:
3
|
Archivo:
Articulos
|
Visitas:
669
|
Comentarios:
2
|
Archivo:
Articulos
|
Visitas:
3177
|
Comentarios:
2
|
Archivo:
Articulos
|
Visitas:
14562
|
Comentarios:
7
|
Archivo:
Articulos
|
Visitas:
1497
|
Comentarios:
3
|
Archivo:
Articulos
|
|
Visitas:
695
|
Comentarios:
2
|
Archivo:
Articulos
|
|
Visitas:
369
|
Comentarios:
0
|
Archivo:
Articulos
|
Visitas:
2034
|
Comentarios:
2
|
Archivo:
Articulos
|
|
|
 |
|
 |