この記事は、SQL Server からデータを取得するときの80020009 エラーを解決するのに役立ちます。
元の製品バージョン: SQL Server
元の KB 番号: 175239
現象
次のエラーは、SQL テーブルから Text
または Blob
型データを含む Active Server Pages (ASP) ファイル内のレコードセットにアクセスするときに発生します。
Microsoft OLE DB Provider for ODBC Drivers エラー '80020009'
原因
次の条件により、エラーが発生する可能性があります。
テキスト/BLOB フィールドは、他の種類のフィールドの前の順序で選択されます。
解決方法
Microsoft SQL Server から BLOB フィールドを処理する場合は、結果セット内の BLOB 以外の列の右側にフィールドを配置する必要があります。 安全に行うには、列を左から右の順序で読み取る必要もあります。そのため、結果セットの最後の 2 つの列として 2 つの BLOB 列がある場合は、最初の列と 2 番目の列を読み取ります。 逆の順序で読み取らないでください。
フィールド選択の正しい順序を示すために、Visual InterDev プロジェクトに新しい ASP ページを作成し、空の ASP ページに次のコードを貼り付けます。 SQL Server に接続するように接続文字列を変更します。
Note
このコードを実行する前に、Username=<username> および PWD=<strong password> を正しい値に変更する必要があります。 ユーザー ID に、データベースでこの操作を実行するための適切なアクセス許可があることを確認します。
<%@ 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>
状態
この動作は仕様によるものです。 ただし、SQL Server 用の 3.7 ドライバー以降で Mdac 2.1 sp2 以降を使用する場合は発生しません。
詳細
SQL Server はネットワーク上のデータを返送しており、クライアントは基本的にネットワーク ネットワーク上で順次読み取られたビットのストリームを受信しています。 バインドされた列 (つまり、値をローカル メモリ バッファーにコピーしてキャッシュできる) では、ドライバーはそれらの列のデータをメモリ バッファーに転送します。 データがローカル バッファーに入ったら、任意の順序でデータを読み取ります。 そのため、すべての列がバインドされている場合 (BLOB ではなく) 結果列を任意の順序で読み取ることができます。
BLOB 列を含めると、列の長さが約 2 ギガバイトになる場合があり、データ アクセス ライブラリでは通常、これらの列をバインドしません。ドライバーは、多くの場合、取得するまで BLOB のサイズを正確に判断できないためです。 また、データ アクセス ライブラリでは通常、大量のメモリが消費され、データ アクセス ライブラリとアプリケーションの両方でキャッシュされる可能性があるため、BLOB データのキャッシュは回避されます。 データ アクセス ドライバーは、BLOB 列の内容を返すように要求された場合、要求された列を読み取る前にシーケンシャル データ ストリームを取得する必要があるため、通常、要求された BLOB 列の前にあるバインドされていない列を破棄します。 そのため、データの取得方法と一致するため、結果セットを左から右に読み取る方が効率的です。
Note
ここでは、SQL Server の動作について説明します。 Oracle と他のクライアント/サーバー DBMS でも同じことを行うことができますが、必須ではありません。
テキスト列を使用しないようにすることをお勧めします。 SQL Server では 2K チャンクの領域が割り当てられるため、テキスト列を使用すると、テキストの長さが小さい場合にストレージを非効率的に使用する可能性があります。 トランザクション ログのダンプに時間がかかるため、バックアップ時間も影響を受けます。 多くの場合、既存のテーブルの PK、チャンク番号列、および varchar (255)
列を含む別のテーブルを作成することをお勧めします。 テキストを必要な数の 255 文字のチャンクに分割し、新しいテーブルにチャンクがある限り多くの行を挿入します。 通常は、ストレージをより効率的に使用し、バックアップをはるかに高速に行うので、コーディング時間を増やす価値があります。