Cursor (base de datos)
En bases de datos, el término cursor se refiere a una estructura de control utilizada para el recorrido (y potencial procesamiento) de los registros del resultado de una consulta.
Un cursor se utiliza para el procesamiento individual de las filas devueltas por el sistema gestor de base de datos para una consulta. Es necesario debido a que muchos lenguajes de programación sufren de lo que en inglés se conoce como impedance mismatch. Por norma general los lenguajes de programación son procedurales y no disponen de ningún mecanismo para manipular conjuntos de datos en una sola instrucción. Debido a ello, las filas deben ser procesadas de forma secuencial por la aplicación. Un cursor puede verse como un iterador sobre la colección de filas que habrá en el set de resultados.
Existen sentencias SQL que no requieren del uso de cursores. Ello incluye la sentencia Insert, así como la mayoría de formas del Update o el Delete. Incluso una sentencia 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
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. No todas 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 OPEN
. 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 FETCH
. 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 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 pas consiste en cerra el cursor utilizando la sentencia CLOSE
.
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.
Cursores de recorrido
Los cursores pueden declararse como de recorrido o no. Si son de recorrido, éste indica la dirección en la que el cursor puede moverse.
Un cursor sin recorrido (non-scrollable en inglés) también se conoce como cursor unidireccional (forward-only en inglés). Cada fila puede ser leida como mucho una vez, y el cursor automáticamente se mueve a la siguiente fila. Una operación de fetch después de haber recuperado la última fila posiciona el cursor detrás de la misma y devuelve SQLSTATE 02000 (SQLCODE +100).
Un cursor de recorrido puede posicionarse en cualquier parte del set de resultados utilizando la sentencia SQL FETCH
. La palabra clace debe ser especificada cuando se declare el cursor. El valor por defecto es NO SCROLL
, aunque algunas capas de aplicación para bases de datos como JDBC pueden aplicar un valor por defecto diferente.
DECLARE cursor_name sensitivity SCROLL CURSOR FOR SELECT ... FROM ...
La posición de un cursor de recorrido puede especificarse de forma relativa a la posición actual del cursor o de forma absoluta a partir del principio del set de resultados.
FETCH [ NEXT | PRIOR | FIRST | LAST ] FROM cursor_name
FETCH ABSOLUTE n FROM cursor_name
FETCH RELATIVE n FROM cursor_name
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.