80020009 error al recuperar datos de SQL

Este artículo le ayuda a resolver el error de 80020009 al recuperar datos de SQL Server.

Versión del producto original: SQL Server
Número de KB original: 175239

Síntomas

El siguiente error se produce al acceder a un conjunto de registros en un archivo de Active Server Pages (ASP) que contiene Text o Blob escribe datos de una tabla SQL:

Error '80020009' del proveedor OLE DB de Microsoft para controladores ODBC

Causa

La siguiente condición puede provocar el error:

Los campos de texto o blob se seleccionan en un orden anterior a otros tipos de campos.

Solución

Al tratar con campos BLOB de Microsoft SQL Server, debe colocarlos a la derecha de las columnas que no son BLOB en el conjunto de resultados. Para estar seguro, también debe leer las columnas en orden 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 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 Visual InterDev y pegue el código siguiente en la página ASP en blanco. Modifique el cadena de conexión para conectarse a la SQL Server:

Nota:

Debe cambiar Username=<username> y PWD=<strong password> a los valores correctos antes de ejecutar este código. Asegúrese de que id. 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 posterior con el controlador 3.7 o posterior para SQL Server.

Más información

SQL Server está devolviendo los datos en la conexión y el cliente recibe esencialmente un flujo de bits leídos secuencialmente en el cable de red. Con las columnas enlazadas (es decir, los valores se pueden copiar en búferes de memoria local y almacenarse en caché allí), el controlador transfiere los datos de esas columnas a búferes de memoria. Una vez que los datos están en búferes locales, puede leer los datos en cualquier orden. Por lo tanto, puede leer las columnas de resultados en cualquier orden cuando todas las columnas están enlazadas (no blobs).

Cuando se incluyen 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, ya que el controlador a menudo no puede determinar exactamente el tamaño del BLOB hasta que se recupera. Además, las bibliotecas de acceso a datos suelen evitar el almacenamiento en caché de datos BLOB, ya que esto puede consumir grandes cantidades de memoria y almacenarlos en caché tanto en la biblioteca de acceso a datos como en 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 el flujo de datos secuencial para poder leer la columna solicitada. Por lo tanto, es más eficaz leer el conjunto de resultados de izquierda a derecha, ya que coincide con la forma en que se recuperan los datos.

Nota:

Esto describe el comportamiento de SQL Server. Oracle y otros DBMS de cliente o servidor pueden hacer lo mismo, pero no es necesario.

Quizás una mejor alternativa es evitar el uso de una columna Text. Dado que SQL Server asigna espacio en fragmentos de 2 000, el uso de columnas de texto puede dar lugar a un uso ineficaz del almacenamiento si la longitud del texto es 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 el PK de la tabla existente, una columna de número de fragmento y una varchar (255) columna. Divida el texto en tantos fragmentos de 255 caracteres necesarios e inserte tantas filas en la nueva tabla como fragmentos. Normalmente vale la pena el tiempo de codificación adicional, ya que hace un uso más eficaz del almacenamiento y las copias de seguridad van mucho más rápido.