Foros del Web » Programando para Internet » ASP Clásico »

Consulta sobre ASP y conexiones ADO

Estas en el tema de Consulta sobre ASP y conexiones ADO en el foro de ASP Clásico en Foros del Web. Buenas tardes: Tengo Windows Xp Profesional SP2 y el IIS 5.1. Hace poco tuve problemas con las páginas ASP pues me mostraba el siguiente error: ...
  #1 (permalink)  
Antiguo 23/12/2006, 19:20
Avatar de freesoftwarrior  
Fecha de Ingreso: marzo-2006
Mensajes: 362
Antigüedad: 18 años, 3 meses
Puntos: 10
Consulta sobre ASP y conexiones ADO

Buenas tardes:
Tengo Windows Xp Profesional SP2 y el IIS 5.1. Hace poco tuve problemas con las páginas ASP pues me mostraba el siguiente error:

Páginas Active Server error 'ASP 0115'
Error inesperado
/empresa/home.asp
Error capturable (C0000005) en un objeto externo. La secuencia de comandos no puede continuar.


Luego de mucho buscar en Google y el Knoledge Base de Microsoft, llegué a la conclusión de que algo había pasado con las librerias del MDAC y encontré la forma de re-instalarlo. La re-instalación (lo comento para quien le pueda interesar) pude hacerla ubicando el archivo mdac.inf en la carpeta windows/inf que es una carpeta oculta. Luego simplemente le digo instalar (botón derecho del mouse) y me pide el CD con el Xp SP2 y listo.

El problema desapareció. Sin embargo ahora aparece más o menos seguido este otro error:

Error de Microsoft VBScript en tiempo de ejecución (0x800A01FB)
Error de excepción: 'open'
/empresa/downloads/index.asp Linea 24


Aunque no es exclusivo del archivo asp indicado, todas las veces que aparece este error hace referencia a la apertura de una base de datos. Yo uso Access y MySQL (he instalado hace tiempo los controladores ODBC para MySQL).

Ahora bien, Microsoft indica que este bug fue resuelto con el MDAC 2.6 (h t t p : / / s u p p o r t . m i c r o s o f t . c o m / k b / 2 6 2 6 8 1) y cito:

Cita:
.......
Causa
This problem occurs because the session variables in Internet Information Server (IIS) 5.0 are stored in the Global Interface Table (GIT), and this causes an access violation with an open recordset when it is stored in a session variable.
.........

......
Estado
Microsoft ha confirmado que se trata de un problema de los productos de Microsoft enumerados al principio de este artículo.
Este error se corrigió en versión 2.6 o posterior Componentes de Acceso datos de Microsoft.
......
Pero con el SP2 se instala el MDAC 2.8 y posteriormente hay una actualización para el mismo en el Windows Update.
La conclusión a la que estoy llegando es que luego de mucho tiempo de usar mis rutinas habituales de conexión de datos, algo esta "sobrecargando" al IIS. Y esta es mi consulta (disculpen la introducción pero lo consideré necesario para establecer el marco de la consulta).

Yo realizo los diseños ASP usando esta secuencia:

1. Creo un archivo INC llamado DB.INC que tiene el siguiente código:

Código:
<%
    Dim Conexion,Tabla
    Set Conexion=Server.CreateObject("adodb.connection")
    Set Tabla1=Server.CreateObject("adodb.recordset")
    Set Tabla2=Server.CreateObject("adodb.recordset")
    Set Tabla3=Server.CreateObject("adodb.recordset")
    Conexion.open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=H:\inetpub\base de datos\Data.mdb"
%>
2. Todos los diseños los hago con INCLUDE de algún tipo. El más común es <!-- #include file="header.asp" --> y el código de este archivo es el siguiente:

Código:
<%
    starttime = Timer()
    Session.lcid=7178
    Response.Expires=0
    Response.ExpiresAbsolute = Now()
    Response.addHeader "pragma", "no-cache"
    Response.addHeader "cache-control","private"
    Response.CacheControl = "no-cache"
    Response.CacheControl = "Private"
    Response.Buffer=True
    
    varNombreDeLaEmpresa="Masters Designers EIRL"
%>

<link rel="SHORTCUT ICON" href="icono.ico">

<!-- <script>
function derecha(e)
{
    if (navigator.appName == 'Netscape' && (e.which == 3 || e.which == 2))
    {alert('Mensaje de advertencia');return false;}
    else if (navigator.appName == 'Microsoft Internet Explorer' && (event.button == 2))
    {alert('Mensaje de advertencia')}
}
document.onmousedown=derecha
</script> -->

<!-- #include file="setup/adovbs.inc" -->
<!-- #include file="setup/db.inc" -->
Eventualmente agrego otros archivos INCLUDE que son comunes a todas las páginas ASP.

3. Luego al empezar a crear cada página, normalmente este es el tipo de rutina de conexión que realizo con ACCESS


Código:
<%
    Temp="Select * From GoogleAdSense Where Tipo='B'"
    Tabla1.Open Temp, Conexion, adOpenStatic, adCmdTable
    While Not Tabla1.EOF
        ....... código a efectuarse.......
        Tabla1.MoveNext
    Wend
    Tabla1.Close
%>
Algunas veces utilizo la conexión sin adOpenStatic ni adCmdTable y es únicamente cuando utilizo el RecordCount que aperturo una tabla con esas características.
Hace relativamente poco he empezado a probar con GetRows

<% Response.Write DBase("contenido","clase,intro","",2) %>

Previamente he cargado un archivo asp de esta forma <!-- #include file="funciones.asp" --> y que tiene rutinas de este tipo

Código:
    Function DBase(tabla, criterio, orden, campo)
        Temp="Select * From " & tabla
       
        ....... operaciones con los datos enviados......       
       
        Tabla1.Open Temp, Conexion
            arrDBData = Tabla1.GetRows()
        Tabla1.Close
       
        iRecFirst   = LBound(arrDBData, 2)
        iRecLast    = UBound(arrDBData, 2)
        For J = iRecFirst To iRecLast
            Response.Write(arrDBData(campo,J)&"<br>")
        Next
    End Function
Pero aún no he uniformizado este tipo de programación en todos los diseños que tengo


Para las conexiones con MySQL uso esta rutina básicamente

Código:
<%
    Set ConMySQL=Server.CreateObject("adodb.connection")
    ConMySQL.Open "DRIVER={MySQL ODBC 3.51 Driver};DATABASE=md_servicios; USER=usuario;PASSWORD=password;OPTION=3;"
    Set rs=server.createobject("ADODB.Recordset")
    rs.Open "Select * From gc_cardinfo",conMySQL,2,3,1
    While Not rs.EOF
        ....... código a utilizarse......
        rs.MoveNext
    Wend
    rs.Close
%>
Como el problema es reconocido como cierto conflicto entre el ISS y el Global Interface Table, presumo que en parte podría ser por la forma de programar que uso, y que con el paso del tiempo puede que haya "desorientado" al IIS o al Xp mismo.

Mi consulta es sobre la forma de programar que utilizo, que mejoras puedo realizar, que consideraciones puedo tener adicionalmente. Soy relativamente novato en esto de programación ASP y reconozco que aún no he profundizado mucho en la programación misma y que estoy bastante "desfasado" respecto a la aparición de ASP.NET, pero quiero enmendar errores y depurar hábitos para lograr mejores productos y resultados.

Agradezco desde ya todo tipo de comentarios constructivos y críticos sobre mi post. Un saludo cordial desde Lima, Perú. Les deseo sinceramente unas fiestas navideñas de lo más alegres y familiares.

Última edición por freesoftwarrior; 24/12/2006 a las 08:24
  #2 (permalink)  
Antiguo 24/12/2006, 01:20
Avatar de pablinff  
Fecha de Ingreso: diciembre-2005
Ubicación: Argentina
Mensajes: 383
Antigüedad: 18 años, 5 meses
Puntos: 7
Re: Consulta sobre ASP y conexiones ADO

Hola que tal!
Bueno básicamente es esto lo que no me convence:
Código:
<%
Dim Conexion,Tabla
Set Conexion=Server.CreateObject("adodb.connection")
Set Tabla1=Server.CreateObject("adodb.recordset")
Set Tabla2=Server.CreateObject("adodb.recordset")
Set Tabla3=Server.CreateObject("adodb.recordset")
Conexion.open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=H:\inetpub\base de datos\Data.mdb"
%>
Porque estás cargando el recordset en vano, además no se porqué directamente no creras una sola variable TABLA, puesto que le estás asignando el mismo valor a todas las variables, osea que da lo mismo que utilices tabla1, tabla2, tabla3 por eso mas vale definí una variable tabla, y llamala cuando la necesites.
Otra cosa, te recomiendo que utilices conexión a la BD sin DNS, es mucho mejor.
También si podrías editar el mensaje y poner el código dentro de etiquetas ["codigo"][/"codigo"], así resulta mucho más fácil de leer, y también poner cual es la linea en donde te marca tu error.
Saludos!
__________________
I'm gonna start a revolution from my bed...
  #3 (permalink)  
Antiguo 24/12/2006, 08:22
Avatar de freesoftwarrior  
Fecha de Ingreso: marzo-2006
Mensajes: 362
Antigüedad: 18 años, 3 meses
Puntos: 10
Re: Consulta sobre ASP y conexiones ADO

Muchas gracias por responder. La razón por la que creo varios objetos recorset es porque muchas veces tengo que trabajar con más de 2 tablas abiertas al mismo tiempo, principalmente cuando, por ejemplo, tengo que tomar un dato de una y mostrar las coincidencias del mismo en otro.

Una consulta...... tu dices que me recomiendas una conexión a la BD sin DNS. Las 2 únicas formas que conozco para conectar una base de datos en ASP es con OLEDB (el que estoy usando) y ODBC(que al inicio usaba por cierto)...... ¿Cuál es la forma a la que te estas refiriéndo?
  #4 (permalink)  
Antiguo 24/12/2006, 09:29
Avatar de pablinff  
Fecha de Ingreso: diciembre-2005
Ubicación: Argentina
Mensajes: 383
Antigüedad: 18 años, 5 meses
Puntos: 7
Re: Consulta sobre ASP y conexiones ADO

Ups! perdón, simplemente me confundí, estás usando efectivamente conexión sin DSN, ahora otra cosa que me di cuenta es que ahí estás especificando la ubicación física de tu BD, probá con esto:
Código:
Dim datos
datos= Server.MapPath ( "/bd/data.mdb" )
conexion.open "Provider=Microsoft.Jet.OLEDB.4.0;Data source="&datos&";"
Fijate en el método MapPath, tenés que poner la dirección virtual de tu BD, ponele que tu url virtual es www.tuweb.com, y tu bd está alojada dentro de una carpeta llamada BD, los datos que tendrías que poner para el método MapPath son "/bd/data.mdb"
__________________
I'm gonna start a revolution from my bed...
  #5 (permalink)  
Antiguo 24/12/2006, 11:43
Avatar de freesoftwarrior  
Fecha de Ingreso: marzo-2006
Mensajes: 362
Antigüedad: 18 años, 3 meses
Puntos: 10
Re: Consulta sobre ASP y conexiones ADO

Gracias por la respuesta....... hubo un tiempo en que utilizaba MapPath pero en algunos casos por alguna razón no funcionaban correctamente..... es muy probable que sea porque como uso IIS bajo Xp tengo esta estructura de carpetas:

Inetpub
-wwwroot
--diseño 1
--diseño 2
--diseño 3

y claro, cada diseño lo cargo así

h t t p : / / l o c a l h o s t /diseño 1

entonces tal vez por eso es que no me funciona el MapPath, pero eso lo podría solucionar si creo directorios virtuales en el IIS.

Tu hiciste un comentario....

Cita:
Porque estás cargando el recordset en vano, además no se porqué directamente no creras una sola variable TABLA, puesto que le estás asignando el mismo valor a todas las variables, osea que da lo mismo que utilices tabla1, tabla2, tabla3 por eso mas vale definí una variable tabla, y llamala cuando la necesites.
y claro, te expliqué que es porque suelo utilizar en algunas oportunidades consultas a más de 1 tabla y son consultas anidadas..... ¿hay alguna alternativa al respecto?

Finalmente......mi modo de programar ¿lo encuentras bien, regular, aceptable, mal, pésimo?...... algo que no hago por cierto es cerrar el objeto Conexion.... ¿esto crees que pueda implicar algo?
  #6 (permalink)  
Antiguo 24/12/2006, 18:52
Avatar de pablinff  
Fecha de Ingreso: diciembre-2005
Ubicación: Argentina
Mensajes: 383
Antigüedad: 18 años, 5 meses
Puntos: 7
Re: Consulta sobre ASP y conexiones ADO

Aver... según tenía entendido (he intentado hacerlo ya), no se pueden tener consultas anidadas, pero tal vez lo he estado haciendo mal, por eso tal vez tendrías que averiguar un poco al respecto.
Con respecto a tu forma de programar, no soy ningún experto, pero de la experiencia que tengo te puedo reclacar los siguientes puntos:
1º Siempre, pero siempre debes cerrar la conexiones a las BD, y tbn setearlas en nada
Código:
conexion.close
Set conexion= Nothing
Esto es muy importante puesto que libera recursos del servidor. Lo mismo con los recordsets
Código:
tabla.close
Set tabla= Nothing
2º Lo de los includes está muy bien desde mi punto de vista, pero te recomiendo que no los guardes con extención *.inc , puesto que si algun malavida quiere obtener la ubicación de tu bd, y/o la contraseña, solo pone en la url la dirección del include y se lo descarga sin más, mas vale guardálas con extenciones *.asp, de esta forma si quieren acceder a tu include desde la url no podrán descargarselo, puesto que al ser un página asp, el servidor intentará interpretarla.
3º Te recomendaría poner en cada página asp un include con estos tags:
Código:
<%@ language="vbscript" %>
<% Option Explicit %>
La primera linea te indica el lenguaje en el que estás programando.
La segunda indica que todas las variables que uses deben ser declaradas, así tu codigo es mas legible y ordenado.
Las variables las declaras así:
Código:
<% 
Dim mivariable1, mivariable2
Dim otravariable, otravariable1
%>
Bueno por ahora esto es lo que me parece que tendrías que corregir, solo son consejos! espero que te sirvan.
Saludos!
__________________
I'm gonna start a revolution from my bed...
  #7 (permalink)  
Antiguo 25/12/2006, 07:39
Avatar de freesoftwarrior  
Fecha de Ingreso: marzo-2006
Mensajes: 362
Antigüedad: 18 años, 3 meses
Puntos: 10
Re: Consulta sobre ASP y conexiones ADO

Aprecio mucho tu respuesta. Cuando me refería a consultas anidadas me refería a algo como esto (tal vez utilice una expresión incorrecta)

Código:
Temp="Select * From Categorias Order By Nombre"
Tabla1.Open Temp, Conexion
While Not Tabla1.EOF


Temp2="Select * From Productos Where Categoria = Tabla1.Fields("ID")"
Tabla2.Open Temp2, Conexion
While Not Tabla2.EOF

....... resto del código

Tabla2.MoveNext
Wend
Tabla2.Close

Tabla1.MoveNext
Wend
Tabla1.Close
Siempre cierro las variables RecordSet pero nunca las he vaciado con el Set tabla = Nothing.

Otro detalle. El archivo INC (que ahora voy a convertir a ASP) siempre lo cargo al inicio. El Conexion.Close que me indicas sólo debo colocarlo al final de la página, ¿verdad?, no al final de cada bucle de consulta, ¿no?

Una consulta final. El error 0x800A01FB que me esta apareciéndo de vez en cuando ¿puede deberse a esto o es más probable a que alguna librería aún esta media dañana en mi Windows?.... Tengo tiempo sin formatear y bueno, he instalado y desinstalado varias cosas en los últimos 2 años.....

Agradezco nuevamente tu apoyo.
  #8 (permalink)  
Antiguo 25/12/2006, 17:42
Avatar de pablinff  
Fecha de Ingreso: diciembre-2005
Ubicación: Argentina
Mensajes: 383
Antigüedad: 18 años, 5 meses
Puntos: 7
Re: Consulta sobre ASP y conexiones ADO

En el ejemplo que me mostrás esás anidando un recordset dentro de otro, y es muy posible que tu error sea por eso, para hacer una consulta o varias debés seguir estos pasos:
1º abrís la conexión a la BD:
Código:
Dim datos
datos= Server.MapPath ( "/bd/data.mdb" )
conexion.open "Provider=Microsoft.Jet.OLEDB.4.0;Data source="&datos&";"
(de esta forma de alguna otra)
2º creas el objeto recordset, para cada consulta así, y una vez lo terminas de ocupar, lo cerrás:
Código:
Set rs = Server.CreateObject("adodb.recordset") 'Yo suelo usar rs para crear el recordset
Temp="Select * From Categorias Order By Nombre"
rs.Open Temp, Conexion
While Not rs.EOF
....
rs.MoveNext
Wend
rs.Close
set rs = nothing ' Lo seteas en nada para liberar recursos del servidor

' Después si querés hacer otra consulta, ejecutás otro recordset igual que el anterior
' Fijate que le puse el mismo nombre que el recordset anterior, puesto que yo no lo ocupo más
Set rs = Server.CreateObject("adodb.recordset") 
Temp="Select * From Categorias Order By Nombre"
rs.Open Temp, Conexion
While Not rs.EOF
....
rs.MoveNext
Wend
rs.Close
set rs = nothing ' Lo seteas en nada para liberar recursos del servidor
' Y así sucesivamente abrís los RS que querés.
3º Y por último cuando terminaste de utilizar la BD, cerrás el objeto de la conexión, en este caso la variable conexion.
Código:
conexion.close
set conexion = nothing 
' Nuevamente seteamos al objeto conexión en nada para que no ocupe espacio en memoria
Bueno respondiendote a la otra pregunta el conexion.close lo tenés que poner cuando termines de utilizar la conexión, indistintamente de la ubicación.
Con respecto a lo de windows... mirá en ese campo nunca entré porque la unica vez que instalé un server en mi pc fué hace mucho y fué el PWS en W98, así que eso no sabría decirte, pero no creo que sea de eso, porque se nota que el anidamiento de recordsets que estás teniendo es el que da error.
Saludos!
__________________
I'm gonna start a revolution from my bed...
  #9 (permalink)  
Antiguo 26/12/2006, 07:45
Avatar de freesoftwarrior  
Fecha de Ingreso: marzo-2006
Mensajes: 362
Antigüedad: 18 años, 3 meses
Puntos: 10
Re: Consulta sobre ASP y conexiones ADO

Nuevamente gracias por tu respuesta. Tal vez aún estoy medio atontado por una mala noche, pero en el ejemplo que me pones me parece ver que son 2 consultas separadas.....

Supongamos que sea este caso. En la tabla CATEGORIAS tengo el nombre de la categoría así como su descripción y un identificador propio, mientras que en la tabla PRODUCTOS tengo los detalles de todos los productos, obviamente con un campo referente a categorias. Si yo deseo presentar en el supuesto caso un listado completo de productos agrupados por categorias y con el nombre y detalle de cada categoría al inicio del listado, yo haría algo asi:

Código:
Temp="Select * From Categorias Order By Nombre"
Tabla1.Open Temp, Conexion
While Not Tabla1.EOF
Response.Write(Tabla1("nombre") & "<br>" & Tabla1("descripcion") & "<hr>")

Temp2="Select * From Productos Where Categoria ='" & Tabla1.Fields("ID") & "' Order By Nombre"
Tabla2.Open Temp2, Conexion
While Not Tabla2.EOF
Response.Write(Tabla1("nombre")&"<br>")
Tabla2.MoveNext
Wend
Tabla2.Close

Tabla1.MoveNext
Wend
Tabla1.Close
Esto es a lo que yo me refiero con consultas anidadas, es decir, una dentro de otra. ¿Es correcta la forma en que lo hago o hay algún vicio o error que estoy comentiendo?

Nuevamente y con sinceridad, muchas gracias por el apoyo que me estas brindando.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 00:30.