80020009 error al recuperar datos de SQL

Este artículo le ayuda a resolver el error 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 obtener acceso a un objeto Recordset en un archivo de páginas Active Server (ASP) que contiene Text o Blob escribe datos de una tabla SQL:

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

Causa

La condición siguiente puede hacer que se produzca el error:

Los campos Text/BLOB se seleccionan en un orden anterior a otros tipos de campos.

Solución

Al trabajar con campos BLOB de Microsoft SQL Server, debe colocarlos a la derecha de las columnas que no son BLOB en ResultSet. Para estar 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 después la segunda. No los lea en orden inverso.

Para demostrar 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 = <strong password> 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 ocurre 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 va a enviar los datos en la red y el cliente, en esencia, está recibiendo una secuencia de bits que se lee secuencialmente en el cable de red. Con las columnas enlazadas (es decir, los valores se pueden copiar en los búferes de la memoria local y almacenarlos en la memoria caché), el controlador transfiere datos de esas columnas a los búferes de la 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 BLOB).

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 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 no es eficiente. Si se solicita al controlador de acceso a datos que devuelva el contenido de una columna BLOB, normalmente se eliminan las columnas no enlazadas que preceden a la columna BLOB solicitada, ya que se debe recuperar la secuencia de datos secuenciales antes de poder leer la columna solicitada. Por lo tanto, es más eficaz leer el ResultSet de izquierda a derecha, ya que esto coincide con la forma en que se recuperan los datos.

Nota

Describe el comportamiento de SQL Server. Oracle y otros DBMS de cliente/servidor podrían hacer lo mismo, pero no es necesario.

Quizás una alternativa mejor es evitar el uso de una columna de texto. Debido a que SQL Server asigna espacio en trozos de 2 k, el uso de columnas de texto puede dar como resultado 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 en volcar el registro de transacciones. Suele ser mejor crear otra tabla que tenga la PK de la tabla existente, una columna de número de fragmentos y una varchar (255) columna. Divida el texto en un máximo de 255 fragmentos de caracteres necesarios y inserte tantas filas en la nueva tabla como fragmentos. Por lo general, merece la pena disponer de tiempo de codificación adicional, ya que el uso más eficiente del almacenamiento y las copias de seguridad es mucho más rápido.