Oracle SQL (Pro*C): conociendo el número de filas de un select de antemano
En un archivo Pro*C, tengo un patrón de búsqueda como este:
EXEC SQL BEGIN DECLARE SECTION;
typedef struct my<em>row</em>t
{
unsigned field1;
unsigned field2;
} my_row;
EXEC SQL END DECLARE SECTION;
void do<em>query()
{
EXEC SQL BEGIN DECLARE SECTION;
struct my</em>row* buffer;
unsigned buffer_size;
EXEC SQL END DECLARE SECTION;
buffer_size = /* algún límite superior relacionado con el número de filas a buscar */;
buffer = (my_row*)malloc(buffer_size * sizeof(my_row));
// Crear my_cursor basado en alguna consulta de selección
// ...
// y ahora:
EXEQ SQL FOR :buffer_size FETCH my_cursor INTO :buffer;
unsigned number_of_fetched_rows = sqlca.sqlerrd[2];
// En este punto, con solo una búsqueda, tengo todas las filas
}
El problema es que, a veces, no se puede estimar un límite superior adecuado. Me refiero a consultas que no devolverán más de unos miles de filas, pero no quiero asignar almacenamiento para, por ejemplo, 5000 filas cuando una consulta particular para una entrada particular solo le dará 500.
¿Existe alguna forma de saber de manera eficiente, antes de hacer la primera búsqueda (por ejemplo, justo después de abrir el cursor), el número de filas a buscar sin ejecutar ninguna consulta de conteo (por razones de rendimiento)?
Mi objetivo es “buscar todo” en un solo pase de la manera más eficiente posible.
Creo que se puede hacer con tablas/registros PL/SQL, pero no sé cómo “guardar” o extraer el contenido de una tabla PL/SQL en un búfer propio utilizando la sintaxis de Pro*C.
davy.ai
Desafortunadamente, no es posible conocer el número exacto de filas a recuperar sin ejecutar una consulta
count(*)
o sin recuperar todas las filas. Sin embargo, puedes usar un arreglo dinámico para asignar memoria según sea necesario mientras recuperas las filas.En Pro*C, puedes usar la instrucción
define
para asignar memoria de forma dinámica para el arreglo. Aquí hay un ejemplo:Este enfoque asignará memoria solo para el número necesario de filas, pero podría potencialmente causar fragmentación de memoria si el tamaño del conjunto de resultados varía ampliamente. Otra alternativa es usar una tabla temporal para almacenar el conjunto de resultados y recuperar desde ella. Este enfoque requeriría un paso adicional para poblar la tabla temporal, pero permitiría recuperar todas las filas de manera eficiente sin asignar demasiada memoria.