Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Las operaciones de una base de datos relacional actúan en un conjunto completo de filas. El conjunto de filas que devuelve una instrucción SELECT está compuesto por todas las filas que satisfacen las condiciones de la cláusula WHERE de la instrucción. Este conjunto completo de filas devuelto por la instrucción se conoce como conjunto de resultados. Las aplicaciones no siempre funcionan de forma eficaz con el conjunto de resultados completo si lo toman como una unidad. Estas aplicaciones necesitan una manera de trabajar con una fila o un pequeño bloque de filas a la vez. Los cursores son una extensión de los conjuntos de resultados que proporcionan dicho mecanismo.
Los cursores amplían el procesamiento del conjunto de resultados al realizar las siguientes acciones:
- Permiten situarse en filas específicas del conjunto de resultados.
- Recuperación de una fila o de un bloque de filas desde la posición actual en el conjunto de resultados.
- Permitir modificaciones de los datos de la fila en la posición actual del conjunto de resultados.
- Admiten distintos niveles de visibilidad de los cambios realizados por otros usuarios en los datos de la base de datos que se presentan en el conjunto de resultados.
Nota
Para obtener una descripción completa de los tipos de cursor SQL Server, consulte Tipo de cursores.
La especificación JDBC admite cursores de solo avance y cursores desplazables que pueden ser sensibles o insensibles a los cambios realizados por otras operaciones, y pueden ser de solo lectura o actualizables. La clase SQLServerResultSet del Microsoft JDBC Driver para SQL Server proporciona esta funcionalidad.
Observaciones
El controlador JDBC de admite los siguientes tipos de cursor y conjunto de resultados junto con las opciones de comportamiento especificadas.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Búfer de respuesta |
|---|---|---|---|---|
| TYPE_FORWARD_ONLY (CONCUR_READ_ONLY) | N/D | Solo avance y solo lectura | direct | full |
La aplicación tiene que hacer un único paso (hacia delante) a través del conjunto de resultados. Este paso es el comportamiento predeterminado y se comporta igual que un cursor TYPE_SS_DIRECT_FORWARD_ONLY. El controlador lee todo el conjunto de resultados del servidor en una memoria durante la ejecución de la instrucción.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Búfer de respuesta |
|---|---|---|---|---|
| TYPE_FORWARD_ONLY (CONCUR_READ_ONLY) | N/D | Solo avance y solo lectura | direct | adaptativo |
La aplicación tiene que hacer un único paso (hacia delante) a través del conjunto de resultados. Se comporta igual que un cursor TYPE_SS_DIRECT_FORWARD_ONLY. El controlador lee las filas del servidor a medida que la aplicación las solicita y reduce el uso de la memoria del lado cliente.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Almacenamiento en búfer de respuesta |
|---|---|---|---|---|
| TYPE_FORWARD_ONLY (CONCUR_READ_ONLY) | Avance rápido | Solo avance y solo lectura | cursor | N/D |
La aplicación tiene que hacer un único paso (hacia delante) a través del conjunto de resultados mediante un cursor de servidor. Se comporta igual que un cursor TYPE_SS_SERVER_CURSOR_FORWARD_ONLY.
Las filas son recuperadas del servidor en bloques que son especificados por el tamaño de captura.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Almacenamiento en búfer de respuesta |
|---|---|---|---|---|
| TYPE_FORWARD_ONLY (CONCUR_UPDATABLE) | Dinámico (solo hacia delante) | Solo hacia adelante, actualizable | N/D | N/D |
La aplicación tiene que hacer un único paso (hacia delante) a través del conjunto de resultados para actualizar una o varias filas.
Las filas son recuperadas del servidor en bloques que son especificados por el tamaño de captura.
El tamaño de captura se fija de forma predeterminada cuando la aplicación llama al método setFetchSize del objeto SQLServerResultSet.
Nota
El controlador JDBC proporciona una característica de almacenamiento en búfer adaptable que le permite recuperar los resultados de la ejecución de una instrucción de SQL Server a medida que la aplicación los necesita, en lugar de todos a la vez. Por ejemplo, si la aplicación tuviera que recuperar una cantidad de datos demasiado grande para la memoria de la aplicación, el almacenamiento en búfer adaptable permite a la aplicación cliente recuperar ese valor como un flujo. El comportamiento predeterminado del controlador es "adaptive". Sin embargo, para obtener el almacenamiento en búfer de conjuntos de resultados adaptables de solo avance, la aplicación tiene que llamar al método setResponseBuffering del objeto SQLServerStatement proporcionando un valor de tipo String "adaptive"". Para ver un código de ejemplo, consulte Actualización de ejemplo de datos grandes.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Almacenamiento en búfer de respuesta |
|---|---|---|---|---|
| TYPE_SCROLL_INSENSITIVE | estática | Desplazable y no actualizable Las actualizaciones, inserciones y eliminaciones en filas externas no son visibles. |
N/D | N/D |
La aplicación requiere una instantánea de base de datos. El conjunto de resultados no se puede actualizar. Solo es compatible CONCUR_READ_ONLY. Todos los demás tipos de simultaneidad producirán una excepción cuando se usen con este tipo de cursor.
Las filas son recuperadas del servidor en bloques que son especificados por el tamaño de captura.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Almacenamiento en búfer de respuesta |
|---|---|---|---|---|
| TYPE_SCROLL_SENSITIVE (CONCUR_READ_ONLY) | Conjunto de claves | Desplazable, de solo lectura. Las actualizaciones de filas externas son visibles y las eliminaciones aparecen como datos que faltan. Las inserciones de filas externas no son visibles. |
N/D | N/D |
La aplicación debe ver los datos modificados solo de las filas existentes.
Las filas son recuperadas del servidor en bloques que son especificados por el tamaño de captura.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Búfer de respuesta |
|---|---|---|---|---|
| TYPE_SCROLL_SENSITIVE (CONCUR_UPDATABLE, CONCUR_SS_SCROLL_LOCKS, CONCUR_SS_OPTIMISTIC_CC, CONCUR_SS_OPTIMISTIC_CCVAL) | Conjunto de claves | Desplazable, actualizable. Las actualizaciones de filas externas e internas son visibles y las eliminaciones aparecen como datos que faltan; las inserciones no son visibles. |
N/D | No aplicable |
La aplicación puede cambiar datos de las filas existentes mediante el objeto ResultSet. La aplicación debe poder ver también los cambios en filas hechos por otros desde fuera del objeto ResultSet.
Las filas son recuperadas del servidor en bloques que son especificados por el tamaño de captura.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Búfer de respuesta |
|---|---|---|---|---|
| TYPE_SS_DIRECT_FORWARD_ONLY | No aplicable | Solo avance y solo lectura | No aplicable | completo o adaptable |
Valor entero = 2003. Proporciona un cursor de solo lectura del lado cliente que está completamente almacenado en búfer. No se crea ningún cursor de servidor.
Solo se admite el tipo de concurrencia CONCUR_READ_ONLY. Todos los demás tipos de simultaneidad producen una excepción cuando se usan con este tipo de cursor.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Almacenamiento en búfer de respuesta |
|---|---|---|---|---|
| TYPE_SS_SERVER_CURSOR_FORWARD_ONLY | Avance rápido | Solo hacia delante | N/D | N/D |
Valor entero = 2004. Rápido y con acceso a todos los datos mediante un cursor de servidor. Se puede actualizar si se usa con el tipo de concurrencia CONCUR_UPDATABLE.
Las filas son recuperadas del servidor en bloques que son especificados por el tamaño de captura.
Para obtener el almacenamiento en búfer adaptable en este caso, la aplicación tiene que llamar explícitamente al método setResponseBuffering del objeto SQLServerStatement proporcionando un valor de tipo String "adaptive" . Para ver un código de ejemplo, consulte Actualización de ejemplo de datos grandes.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Almacenamiento en búfer de respuesta |
|---|---|---|---|---|
| TYPE_SS_SCROLL_STATIC | estática | No se reflejan las actualizaciones de otros usuarios. | N/D | N/D |
Valor entero = 1004. La aplicación requiere una instantánea de base de datos. Esta opción es el sinónimo específico de SQL Server para JDBC TYPE_SCROLL_INSENSITIVE y tiene el mismo comportamiento de configuración de simultaneidad.
Las filas son recuperadas del servidor en bloques que son especificados por el tamaño de captura.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Almacenamiento en búfer de respuesta |
|---|---|---|---|---|
| TYPE_SS_SCROLL_KEYSET (CONCUR_READ_ONLY) | Conjunto de claves | Desplazable, de solo lectura. Las actualizaciones de filas externas son visibles y las eliminaciones aparecen como datos que faltan. Las inserciones de filas externas no son visibles. |
N/D | N/D |
Valor entero = 1005. La aplicación solo tiene que ver los datos cambiados para las filas existentes. Esta opción es el sinónimo específico de SQL Server para JDBC TYPE_SCROLL_SENSITIVE y tiene el mismo comportamiento de configuración de simultaneidad.
Las filas son recuperadas del servidor en bloques que son especificados por el tamaño de captura.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Almacenamiento en búfer de respuesta |
|---|---|---|---|---|
| TYPE_SS_SCROLL_KEYSET (CONCUR_UPDATABLE, CONCUR_SS_SCROLL_LOCKS, CONCUR_SS_OPTIMISTIC_CC, CONCUR_SS_OPTIMISTIC_CCVAL) | Conjunto de claves | Desplazable, actualizable. Las actualizaciones de filas externas e internas son visibles y las eliminaciones aparecen como datos que faltan; las inserciones no son visibles. |
N/D | N/D |
Valor entero = 1005. La aplicación tiene que cambiar datos o ver datos cambiados para las filas existentes. Esta opción es el sinónimo específico de SQL Server para JDBC TYPE_SCROLL_SENSITIVE y tiene el mismo comportamiento de configuración de simultaneidad.
Las filas son recuperadas del servidor en bloques que son especificados por el tamaño de captura.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Búfer de respuesta |
|---|---|---|---|---|
| TYPE_SS_SCROLL_DYNAMIC (CONCUR_READ_ONLY) | Dinámico | Desplazable, de solo lectura. Las actualizaciones e inserciones de las filas externas son visibles, y las eliminaciones aparecen como datos que faltan de forma transitoria en el búfer de captura actual. |
N/D | N/D |
Valor entero = 1006. La aplicación debe ver los datos cambiados para las filas existentes, así como las filas insertadas y eliminadas durante la duración del cursor.
Las filas son recuperadas del servidor en bloques que son especificados por el tamaño de captura.
| Tipo de conjunto de resultados (cursor) | Tipo de cursor de SQL Server | Características | Seleccionar método | Búfer de respuesta |
|---|---|---|---|---|
| TYPE_SS_SCROLL_DYNAMIC (CONCUR_UPDATABLE, CONCUR_SS_SCROLL_LOCKS, CONCUR_SS_OPTIMISTIC_CC, CONCUR_SS_OPTIMISTIC_CCVAL) | Dinámico | Desplazable, actualizable. Las actualizaciones e inserciones de las filas externas e internas son visibles, y las eliminaciones aparecen como datos que faltan de forma transitoria en el búfer de captura actual. |
N/D | N/D |
Valor entero = 1006. La aplicación puede cambiar datos para las filas existentes, o insertar o eliminar filas, mediante el objeto ResultSet. La aplicación debe poder ver también los cambios, inserciones y eliminaciones en filas hechos por otros desde fuera del objeto ResultSet.
Las filas son recuperadas del servidor en bloques que son especificados por el tamaño de captura.
Colocación de los cursores
Los cursores TYPE_FORWARD_ONLY, TYPE_SS_DIRECT_FORWARD_ONLY y TYPE_SS_SERVER_CURSOR_FORWARD_ONLY solo son compatibles con el método de colocación next.
El cursor TYPE_SS_SCROLL_DYNAMIC no admite los métodos absolute y getRow. El método absolute puede aproximarse mediante una combinación de llamadas a los métodos first y relative para cursores dinámicos.
Solo los cursores TYPE_FORWARD_ONLY, TYPE_SS_DIRECT_FORWARD_ONLY, TYPE_SS_SERVER_CURSOR_FORWARD_ONLY, TYPE_SS_SCROLL_KEYSET y TYPE_SS_SCROLL_STATIC admiten el método getRow. El método getRow con todos los tipos de cursor de solo avance devuelve el número de filas leídas hasta el momento a través del cursor.
Nota
Cuando una aplicación hace una llamada que no se admite para colocar un cursor o hace una llamada que no se admite al método getRow, se inicia una excepción con el mensaje "La operación solicitada no es compatible con este tipo de cursor".
Solo los cursores TYPE_SS_SCROLL_KEYSET y los cursores TYPE_SCROLL_SENSITIVE equivalentes exponen las filas eliminadas. Si el cursor se coloca en una fila eliminada, los valores de las columnas no están disponibles, y el método rowDeleted devuelve "true". Las llamadas a los métodos get<Type> provocan que se inicie una excepción y que se muestre un mensaje similar a “No se puede obtener un valor de una fila eliminada”. Las filas eliminadas no se pueden actualizar. Si intenta llamar a un método update<Type> en una fila eliminada, se produce una excepción con el mensaje: «No se puede actualizar una fila eliminada». El cursor TYPE_SS_SCROLL_DYNAMIC tiene el mismo comportamiento hasta que el cursor se mueve fuera del búfer de captura actual.
Los cursores de avance y dinámicos muestran las filas eliminadas de forma similar, pero solo mientras permanezcan accesibles en el búfer de recuperación. Con los cursores hacia delante, este comportamiento es bastante sencillo. En los cursores dinámicos, es más complejo cuando el tamaño de recuperación es mayor que 1. Una aplicación puede mover el cursor hacia delante y hacia atrás dentro de la ventana que se define en el búfer de captura, pero la fila eliminada desaparecerá cuando el búfer de captura original en el que se actualizó permanezca. Si una aplicación no desea ver filas eliminadas transitorias mediante cursores dinámicos, se debe usar una captura relativa (0).
Si los valores de la clave de una fila de cursores TYPE_SS_SCROLL_KEYSET o TYPE_SCROLL_SENSITIVE se actualizan con el cursor, la fila conserva su posición original en el conjunto de resultados, independientemente de si la fila actualizada cumple los criterios de selección del cursor. Si la fila se actualizó fuera del cursor, una fila eliminada aparecerá en la posición original de la fila, pero solamente aparecerá en el cursor si otra fila con los valores de la nueva clave estaba presente en el cursor y se ha eliminado desde entonces.
Con los cursores dinámicos, las filas actualizadas conservarán su posición dentro del búfer de captura hasta que el búfer de captura que permanece defina la ventana. Las filas actualizadas podrían reaparecer después en posiciones diferentes dentro del conjunto de resultados, o podrían desaparecer por completo. Las aplicaciones que tengan que evitar incoherencias transitorias en el conjunto de resultados deben usar un tamaño de captura de 1 (el valor predeterminado es de 8 filas con la concurrencia CONCUR_SS_SCROLL_LOCKS y de 128 filas con otros tipos de concurrencia).
Conversión de cursores
En ocasiones, SQL Server puede elegir implementar un tipo de cursor que no sea el solicitado, lo que se conoce como conversión implícita del cursor (o degradación del cursor).
Con SQL Server 2000 (8.x), cuando se actualizan los datos mediante el conjunto de resultados ResultSet.TYPE_SCROLL_SENSITIVE y ResultSet.CONCUR_UPDATABLE, se produce una excepción con el mensaje "El cursor es de solo lectura". Esta excepción se debe a que SQL Server 2000 (8.x) ha realizado una conversión implícita del cursor para ese conjunto de resultados y no devolvió el cursor actualizado que se ha solicitado.
Como solución alternativa para este problema, puede elegir una de las siguientes soluciones:
- Asegurarse de que la tabla subyacente tiene una clave principal
- Use SQLServerResultSet.TYPE_SS_SCROLL_DYNAMIC en lugar de ResultSet.TYPE_SCROLL_SENSITIVE mientras crea una instrucción.
Actualización de cursores
Las actualizaciones en contexto se admiten para los cursores cuyo tipo y simultaneidad lo permiten. Si el cursor no se coloca en una fila actualizable en el conjunto de resultados (no se realizó correctamente ninguna llamada de método get<Type>), una llamada a un método update<Type> producirá una excepción con el mensaje “El conjunto de resultados no tiene ninguna fila actual”. La especificación de JDBC indica que surge una excepción cuando se llama a un método de actualización para una columna de un cursor que sea CONCUR_READ_ONLY. En las situaciones en las que la fila no es actualizable (por ejemplo, debido a un conflicto de simultaneidad optimista como una actualización o eliminación en competencia), la excepción podría no iniciarse hasta que se llame a insertRow, a updateRow o a deleteRow.
Después de llamar a update<Type>, no se puede acceder a la columna afectada mediante get<Type> hasta que se llame a updateRow o cancelRowUpdates. Este comportamiento evita problemas en los que una columna se actualiza utilizando un tipo distinto del que devuelve el servidor, y las llamadas posteriores al método getter podrían invocar conversiones de tipo en el cliente que den resultados imprecisos. Las llamadas a get<Type> lanzarán una excepción con el mensaje: "No se puede acceder a las columnas actualizadas hasta que se haya llamado a updateRow() o a cancelRowUpdates()".
Nota
Si se llama al método updateRow cuando no se hayan actualizado las columnas, el controlador JDBC iniciará una excepción con el mensaje "Se llamó a updateRow() cuando no se han actualizado las columnas".
Después de llamar a moveToInsertRow, se iniciará una excepción si se llama a cualquier otro método que no sea get<Type>, update<Type>, insertRow y otros métodos de posicionamiento de los cursores (incluido moveToCurrentRow) en el conjunto de resultados. El método moveToInsertRow coloca efectivamente el conjunto de resultados en modo de inserción, y los métodos de posicionamiento del cursor ponen fin al modo de inserción. Las llamadas de posicionamiento relativo del cursor mueven el cursor con respecto a la posición en la que se encontraba antes de que se llamara a moveToInsertRow. Después de las llamadas de posicionamiento del cursor, la posición de destino final del cursor pasa a ser la nueva posición del cursor.
Si la llamada para colocar un cursor que se realizó mientras se estaba en el modo de inserción no tiene éxito, la posición del cursor después de la llamada que no tuvo éxito es la posición original del cursor antes de que se llamara a moveToInsertRow. Si insertRow da error, el cursor permanece en la fila de inserción y en el modo de inserción.
Las columnas de la fila de inserción están inicialmente en estado no inicializado. Las llamadas al método update<Type> establecen el estado de las columnas como inicializado. Una llamada al método get<Type> para una columna sin inicializar inicia una excepción. Una llamada al método insertRow devuelve todas las columnas de la fila de inserción en un estado sin inicializar.
Si alguna columna está sin inicializar cuando se llama al método insertRow, se inserta el valor predeterminado para la columna. Si no hay ningún valor predeterminado pero la columna admite valores NULL, se inserta el valor NULL. Si no hay ningún valor predeterminado y la columna no admite valores NULL, el servidor devolverá un error y se iniciará una excepción.
Nota
Las llamadas al método getRow devuelven 0 cuando se está en modo de inserción.
El controlador JDBC no admite actualizaciones ni eliminaciones posicionadas. Según la especificación de JDBC, el método setCursorName no tiene ningún efecto y el método getCursorName iniciará una excepción si se llama.
Los cursores estáticos y de solo lectura nunca son actualizables.
SQL Server restringe los cursores de servidor a un solo conjunto de resultados. Si un lote o procedimiento almacenado contiene varias instrucciones, se debe usar un cursor de cliente de solo lectura y de solo avance.