Compartir vía


Cursores dinámicos de ODBC

Un cursor dinámico es solo eso: dinámico. Puede detectar los cambios realizados en la pertenencia, el orden y los valores del conjunto de resultados después de abrir el cursor. Por ejemplo, suponga que un cursor dinámico captura dos filas y después otra aplicación actualiza una de esas filas y elimina la otra. Si después el cursor dinámico intenta volver a capturar esas filas, no encontrará la que se ha eliminado, pero devolverá los valores nuevos de la fila actualizada.

Los cursores dinámicos detectan todas las actualizaciones, eliminaciones e inserciones, tanto propias como las realizadas por otros. (Esto está sujeto al nivel de aislamiento de la transacción, tal como lo establece el atributo de conexión SQL_ATTR_TXN_ISOLATION). La matriz de estado de fila especificada por el atributo de instrucción SQL_ATTR_ROW_STATUS_PTR refleja estos cambios y puede contener SQL_ROW_SUCCESS, SQL_ROW_SUCCESS_WITH_INFO, SQL_ROW_ERROR, SQL_ROW_UPDATED y SQL_ROW_ADDED. No puede devolver SQL_ROW_DELETED porque un cursor dinámico no devuelve filas eliminadas fuera del conjunto de filas y, por tanto, ya no reconoce la existencia de la fila eliminada en el conjunto de resultados o su elemento correspondiente en la matriz de estado de fila. SQL_ROW_ADDED solo se devuelve cuando una fila se ha actualizado mediante una llamada a SQLSetPos, no cuando se ha actualizado mediante otro cursor.

Una manera de implementar cursores dinámicos en la base de datos es crear un índice selectivo que defina la pertenencia y el orden del conjunto de resultados. Dado que el índice se actualiza cuando otros realizan cambios, un cursor basado en este índice es sensible a todos los cambios. Se puede ampliar la selección dentro del conjunto de resultados definido por este índice mediante el procesamiento a lo largo del índice.

Los cursores dinámicos se pueden simular exigiendo que el conjunto de resultados se ordene mediante una clave única. Con esta restricción, las capturas se realizan mediante la ejecución de una instrucción SELECT cada vez que el cursor captura filas. Por ejemplo, supongamos que el conjunto de resultados se define mediante esta instrucción:

SELECT * FROM Customers ORDER BY Name, CustID  

Para capturar el siguiente conjunto de filas de este conjunto de resultados, el cursor simulado establece los parámetros de la siguiente instrucción SELECT en los valores de la última fila del conjunto de filas actual y, a continuación, la ejecuta:

SELECT * FROM Customers WHERE (Name > ?) AND (CustID > ?)  
   ORDER BY Name, CustID  

Esta instrucción crea un segundo conjunto de resultados, cuyo primer conjunto de filas es el siguiente conjunto de filas del conjunto de resultados original; en este caso, el conjunto de filas de la tabla Clientes. El cursor devuelve este conjunto de filas a la aplicación.

Es interesante tener en cuenta que, en realidad, un cursor dinámico implementado de esta manera crea muchos conjuntos de resultados, lo que le permite detectar cambios en el conjunto de resultados original. La aplicación nunca aprende de la existencia de estos conjuntos de resultados auxiliares; simplemente aparece como si el cursor pudiera detectar cambios en el conjunto de resultados original.