Error de PRB: 80020009 al recuperar datos de SQL


Síntomas


El error siguiente se produce al obtener acceso a un conjunto de registros en un archivo de páginas Active Server (ASP) que contiene datos de tipo "texto" o "BLOB" de una tabla SQL:
Error ' 80020009 ' de proveedor OLE DB de Microsoft para controladores ODBC

Causa


La condición siguiente puede provocar el error:
Los campos texto/BLOB se seleccionan en un orden que precede a otros tipos de campos.

Resolución


Al tratar los campos BLOB de Microsoft SQL Server, debe colocarlos a la derecha de las columnas no BLOB en el conjunto de resultados. Para que sea seguro, también debe leer las columnas de izquierda a derecha, por lo que si tiene dos columnas BLOB como las dos últimas columnas del conjunto de resultados, lea la primera y luego la segunda. No los lea en el orden inverso. Para mostrar el orden correcto de selección de campos, cree una nueva página ASP en un proyecto de Visual InterDev y pegue el siguiente código en la página ASP en blanco. Modifique la cadena de conexión para conectarse a SQL Server:Nota debe cambiar username =<username> y PWD =<contraseña segura> a los valores correctos antes de ejecutar este código. Asegúrese de que el identificador de usuario tiene los permisos adecuados para realizar esta operación en la base de datos.
   <%@ Language=VBScript %>   <HTML>   <BODY bgcolor=white>   <%      Set cn = Server.CreateObject("ADODB.Connection")      Set rs = Server.CreateObject("ADODB.Recordset")      'Open the connection.      cn.Open "dsn=yoursystemdsn;Username=<username>;PWD=<strong password>;database=pubs;"      'Open the recordset.      'Notice that the Blob field, pr_info, is last in the field order.      rs.Open "select pub_id, pr_info from pub_info", cn      While Not rs.EOF         Response.Write "<P>PR Info:<P>" & rs("pr_info")         Response.Write "<P>That was the PR Info for PubID " &                           rs("pub_id")         rs.MoveNext      Wend   %>   </BODY>   </HTML>

Estado


Este comportamiento es una característica del diseño de la aplicación. Sin embargo, no se produce cuando se usa MDAC 2.1 SP2 o una versión posterior con el controlador de 3,7 o una versión posterior para SQL Server. puede descargar la última versión de Microsoft Data Access Components desde el siguiente sitio web de Microsoft:

Más información


SQL Server está enviando los datos en el cable y el cliente, en esencia, está recibiendo una secuencia de bits de lectura secuencialmente en el cable de red. Con las columnas enlazadas (es decir, los valores se pueden copiar en búferes de la memoria local y almacenarlos en la memoria caché), el controlador transfiere los datos de esas columnas a los búferes de memoria. Una vez que los datos están en búferes locales, puede leer los datos en cualquier orden. Por consiguiente, puede leer las columnas de resultados en cualquier orden cuando todas las columnas están enlazadas (no blobs). Cuando incluye columnas BLOB, la longitud de la columna puede ser de aproximadamente 2 gigabytes y las bibliotecas de acceso a datos normalmente no enlazan esas columnas porque el controlador a menudo no puede determinar exactamente cuánto es el BLOB hasta que se recupera. Además, las bibliotecas de acceso a datos normalmente evitan el almacenamiento en caché de datos BLOB, ya que esto puede consumir gran cantidad de memoria y almacenarla en caché en la biblioteca de acceso a datos y la aplicación es ineficaz. Si se solicita al controlador de acceso a datos que devuelva el contenido de una columna BLOB, normalmente descarta las columnas no enlazadas que preceden a la columna BLOB solicitada, ya que debe recuperar la secuencia de datos secuenciales antes de que pueda leer la columna solicitada. Por lo tanto, es más eficaz leer el conjunto de resultados de izquierda a derecha, ya que esto se corresponde con la forma en que se recuperan los datos. Tenga en cuenta que esto describe el comportamiento de SQL Server. Oracle y otros DBMS de cliente/servidor pueden hacer lo mismo, pero no es necesario. Quizás una alternativa mejor es evitar usar una columna de texto. Debido a que SQL Server asigna espacio en trozos de 2 KB, el uso de columnas de texto puede dar lugar a un uso ineficaz del almacenamiento si la longitud del texto es muy pequeña. El tiempo de copia de seguridad también se ve afectado porque tarda más tiempo en volcar el registro de transacciones. A menudo es mejor crear otra tabla que tenga la PK de la tabla existente, una columna de número de campo y una columna VARCHAR (255). Divida el texto en tantos fragmentos de caracteres 255 necesarios e inserte tantas filas en la nueva tabla como fragmentos. Por lo general, merece el tiempo de programación adicional, ya que el uso más eficaz del almacenamiento y de las copias de seguridad es mucho más rápido.