Utilizando GetRows
La mayoría de la gente, cuando quiere mostrar datos de una
tabla en una página web para, por ejemplo, dibujar una tabla HTML con los resultados
de la consulta, utiliza un bucle sencillo para ir imprimiendo, registro a registro...
Sin embargo, existe un método mucho menos intenso para el servidor y mucho más
rápido. Este artículo explica qué es, cómo y por qué se utiliza GetRows.
Introducción
Seguro que el siguiente fragmento de código te es familiar:
Dim oConn, rs, SQL
SQL="SELECT * FROM Tabla"
set oConn = Server.CreateObject("ADODB.Connection")
oConn.Open "..."
set rs = oConn.Execute(SQL)
Response.Write("<TABLE>")
while not rs.EOF
Response.Write("<TR>")
Response.Write("<TD>" &
rs.Fields("Nombre") & "</TD>")
Response.Write("<TD>" &
rs.Fields("Fecha") & "</TD>")
Response.Write("<TD>" &
rs.Fields("Numero") & "</TD>")
Response.Write("</TR>")
rs.MoveNext
wend
Response.Write("</TABLE>")
rs.Close
set rs = nothing
oConn.Close
set oConn = nothing
Efectivamente, es el típico código para mostrar una tabla
en una página ASP. Sin embargo ¿has parado a pensar si este código es eficiente?
¿Cómo se comporta este código cuando es ejecutado?
Os lo voy a explicar. Supongamos una tabla como la anterior,
con 3 campos, y 200 registros. ¿Sabes cuántos viajes al servidor tiene que hacer
este script?
600 (200 registros x 3 campos)
+200 (por cada rs.MoveNext)
+200 (por cada vez que comprobamos rs.EOF)
======
1000 peticiones para mostrar 200 filas.
De acuerdo, existe la propiedad del objeto Recordset CacheSize,
que define cúantos registros se trae ADO del servidor en cada petición. De todas
formas, estos viajes, al traer más cantidad de datos, también son más costosos,
aunque reducen el stress sobre el servidor.
GetRows
¿Por qué no utilizar GetRows y reducirlo a 1 petición?
Este método del objeto Recordset vuelca el contenido resultante
de ejecutar la consulta SQL en un vector bidimensional. Tras ejecutar:
Dim miTabla
miTabla = rs.GetRows
Podemos incluso cerrar y destruir los objetos Recordset y
Connection, porque todos los datos están ya en el vector miTabla.
Las ventajas son obvias: nos deshacemos de la relación con
el cursor o el Recordset y la base de datos, liberamos mucho antes la memoria
para otros scripts y desde luego favorecemos a la base de datos porque la dejamos
tranquila mucho antes. :-)
Aunque suene a broma, este último punto es muy beneficioso
para Access, que no soporta especialmente bien muchos usuarios concurrentes.
Una vez volcados los datos, podemos recorrer el vector como
hacemos con cualquier otro, imprimirlo, etc. Este vector, como he dicho, tiene
dos dimensiones: la primera dimensión corresponde a los campos que tendríamos
en rs.Fields y la segunda es el número de registros devueltos.
Así que, para escribir el campo Nombre del primer registro,
en el ejemplo anterior, haríamos:
Response.Write miTabla(0,0)
que es el 1er campo (0) de la primera fila(0).
Aquí tenéis el ejemplo anterior, utilizando GetRows:
Dim oConn, rs, SQL, miTabla
Dim I, J
'Para recorrer el vector
SQL="SELECT * FROM Tabla"
set oConn = Server.CreateObject("ADODB.Connection")
oConn.Open "..."
set rs = oConn.Execute(SQL)
miTabla = rs.GetRows
'Liberamos los objetos ya!!
rs.Close
set rs = nothing
oConn.Close
set oConn = nothing
Response.Write("<TABLE>")
'Recorremos el vector
'Desde el primero hasta el último "registro"...
for I = 0 to UBound(miTabla,2)
'Abrimos una nueva fila
Response.Write("<TR>")
'Desde el primero hasta el último "campo"...
for J = 0 to Ubound(miTabla, 1)
'Imprimo una celda para cada campo
Response.Write("<TD>" &
miTabla(J, I) & "</TD>")
next
Response.Write("</TR>")
next
Response.Write("</TABLE>")
¿Fácil no? Si no estás acostumbrado/a a trabajar con vectores,
asegúrate de leer este artículo.
GetRows, además, permite recorrer el conjunto de registros
en cualquier orden, ir directamente a uno de ellos, retroceder, avanzar cuatro...
sin tener que preocuparnos con los cursores del objeto Recordset.
Otra gran ventaja a favor de GetRows es que contar el número
de registros es tan sencillo como:
total = UBound(miTabla,2)+1
Se acabaron los -1 devueltos por RecordCount, o los problemas
con "SELECT TOP..."
Para que os hagáis una idea, los Foros de esta web están
hechos utilizando exclusivamente GetRows... Es la única forma de avanzar para
ver si después hay una respuesta, etc. para ir incluyendo las imágenes que simulan
el árbol de mensajes. Hacer eso mismo utilizando métodos de movimiento normales
como MoveNext sería imperdonable para la velocidad de la página.
¿Tengo que utilizar números?
Vale, admito que rs.Fields("Nombre") es bastante
más descriptivo que miTabla(0, I). Afortunadamente, para cada problema existe
una solución, así que vamos a tirar de variables.
Podemos definir los índices del vector con nombres simbólicos
si creamos variables con el valor númerico en ellas. En nuestro caso, sabemos
que vamos a utilizar Nombre(0), Fecha(1) y Numero(2), así que escribimos:
Dim Nombre
Dim Fecha
Dim Numero
Nombre = 0
Fecha = 1
Numero = 2
y nuestro bucle anterior queda convertido en:
...
for I = 0 to UBound(miTabla,2)
'Abrimos una nueva fila
Response.Write("<TR>")
Response.Write("<TD>" & miTabla(Nombre, I) &
"</TD>")
Response.Write("<TD>" & miTabla(Fecha, I) &
"</TD>")
Response.Write("<TD>" & miTabla(Numero, I) &
"</TD>")
Response.Write("</TR>")
next
Lo cual se parece muchísimo al código al que estamos acostumbrados
y es mil veces mejor. El valor de cada índice es sustituido por la variable
que contiene ese número y que hemos nombrado de forma que resulte muy explícita.
¡Perfecto!
En resumen...
En fin, espero que este artículo te haya convencido. No necesitas
utilizar otra cosa que no sea GetRows nunca más para mostrar datos de base de
datos.
P.D: Hay otro método aún más rápido que GetRows... Su nombre
es GetString, pero sólo es útil para determinadas tareas, y es el tema de otro
artículo... ;-)
"Carlos de la Orden es el creador de
ASPFácil.com, sitio web
dedicado extensivamente al desarrollo de sitios web con Active Server Pages."
|