Diferencia entre revisiones de «Cursor (base de datos)»

Contenido eliminado Contenido añadido
m Revertidos los cambios de 187.194.249.114 (disc.) a la última edición de CEM-bot
Línea 5:
Existen sentencias [[SQL]] que no requieren del uso de cursores. Ello incluye la sentencia [[SQL#INSERT|Insert]], así como la mayoría de formas del [[Sentencia Update|Update]] o el [[Sentencia Delete|Delete]]. Incluso una sentencia [[Sentencia Select|Select]] puede no requerir un cursor si se utiliza en la variante de ''SELECT...INTO'', ya que esta variante sólo devuelve una fila.
 
== Trabajando con cursores kk==
==
 
Esta sección introduce la forma en la que los cursores deberían ser utilizados en aplicaciones con SQL empotrado, según el estándar [[SQL:2003]]. <u>No todas</u> las capas de aplicación para sistemas de bases de datos relacionales siguen este estándar, utilizando en su lugar una interfaz diferente, como CLI o [[JDBC]].
 
Un cursor es creado utilizando la sentencia DECLARE CURSOR. Es obligatorio asignarle un nombre.
 
DECLARE ''cursor_name'' CURSOR FOR SELECT... FROM...
 
Antes de ser utilizado, el cursor debe ser abierto con una sentencia <code>OPEN</code>. Como resultado de esta sentencia, el cursor se posiciona ''antes'' de la primera fila del set de resultados.
 
OPEN ''cursor_name''
 
Un cursor se posiciona en una fila específica del set de resultados con la sentencia <code>FETCH</code>. Una sentencia fetch transfiere la información de la fila a la aplicación. Una vez todas las filas han sido procesadas o la sentencia fetch queda posicionada en una fila no existente (ver [[#Cursores de recorrido|cursores de recorrido]] más abajo), el SGBD devuelve un SQLSTATE '02000' (acompañado normalmente de un SQLCODE +100) para indicar el final del set de resultados.
 
FETCH ''cursor_name'' INTO...
 
El último paso consiste en cerrar el cursor utilizando la sentencia <code>CLOSE</code>.
 
CLOSE ''cursor_name''
 
Una vez un cursor está cerrado puede reabrirse de nuevo, lo cual implica que la consulta es reevaluada y se crea un nuevo set de resultados.
 
== Trabajando con cursores kk
==
 
Esta sección ickkck introduce la forma en la que los cursores deberían ser utilizados en aplicaciones con SQL empotrado, según el estándar [[SQL:2003]]. <u>No todas</u> las capas de aplicación para sistemas de bases de datos relacionales siguen este estándar, utilizando en su lugar una interfaz diferente, como CLI o [[JDBC]].
 
Un cursor es creado utilizando la sentencia DECLARE CURSOR. Es obligatorio asignarle un nombre.
Línea 70 ⟶ 46:
 
Los cursores de recorrido pueden potencialmente acceder a la misma fila del set de resultados múltiples veces. Por lo tanto, modificaciones de datos (insert, update, delete) realizadas por otras transacciones podrían tener un impacto en el set de resultados. Un cursor puede ser '''sensible''' o '''insensible''' a tales modificaciones. Un cursor sensible recogería las modificaciones que afectarían al set de resultados, mientras que uno insensible no. Adicionalmente, un cursor puede ser '''asensible''', en cuyo caso el SGBD intentará, en la medida de lo posible, aplicar los cambios como si fuera sensible.
 
=== WITH HOLD ===
 
Por norma general los cursores son cerrados automáticamente al final de una transacción, es decir, cuando se ejecuta un [[Commit|COMMIT]] o un [[Rollback|ROLLBACK]], o bien cuando se da un cierre implícito de la transacción. Este comportamiento puede ser cambiado si el cursor es declarado utilizando la cláusula WITH HOLD (por defecto cualquier cursor será WITHOUT HOLD). Un cursor declarado con esta cláusula se mantiene abierto tras un COMMIT y se cierra después de un ROLLBACK, aunque algunos [[SGBD]] se desvían de este comportamiento estándar y mantienen abierto estos cursores después de un ROLLBACK.
 
DECLARE ''cursor_name'' CURSOR '''WITH HOLD''' FOR SELECT... FROM...
 
Cuando se ejecuta un COMMIT, el cursor WITH HOLD se posiciona ''antes'' de la siguiente fila o [[registro (base de datos)|registro]]. Por lo tanto, una operación UPDATE o DELETE posicionada sólo funcionará después de haber realizado primero un FETCH en la misma transacción.
 
Tomese nota de que JDBC define los cursores como WITH HOLD por defecto. Esto se hace porque JDBC activa la opción de '''auto-commit''' por defecto. Debido a la sobrecarga habitual relacionada con el auto-commit y los cursores WITH HOLD, ambos deberían estar explícitamente desactivados en el nivel de conexión.
 
=== Sentencias Update/Delete posicionadas ===
 
Los cursores no sólo pueden ser utilizados para extraer información de la base de datos a una aplicación, sino que también sirven para identificar una fila a modificar o borrar en una [[tabla (base de datos)|tabla]]. El estándar [[SQL:2003]] define para tal fin las sentencias '''posicionadas Update y Delete '''. Estas sentencias no utilizan una cláusula WHERE normal (con predicados de condición). En cambio, el cursor identifica la fila, para lo cual debe ser abierto y posicionado en la misma utilizando la sentencia <code> FETCH </code>.
 
UPDATE ''table_name''
SET ...
WHERE '''CURRENT OF''' ''cursor_name''
 
DELETE
FROM ''table_name''
WHERE '''CURRENT OF''' ''cursor_name''
 
El cursor debe operar sobre un set de resultados que sea '''modificable''' para que una sentencia posicionada UPDATE o DELETE pueda ejecutarse con éxito. En caso contrario, el SGBD no sabría como aplicar los cambios en los datos a las tablas subyacentes referidas en el cursor.
 
=== Cursores en transacciones distribuidas ===
 
Usar cursores en transacciones distribuidas (entornos X/open XA), que son controladas utilizando un [[monitor de transacciones]], no es diferente que usar cursores en transacciones no distribuidas.
 
Aun así, se debe prestar atención al usar cursores [[#WITH HOLD|WITH HOLD]]. Las conexiones pueden ser usadas por diferentes aplicaciones. Por lo tanto, una vez una transacción ha sido confirmada y ha terminado, una transacción subsecuente (que fuera de otra aplicación) podría heredar cursores WITH HOLD ya existentes. Este es un punto que los programadores de aplicaciones deben tener en cuenta.
 
=== WITH HOLD ===