[ACC2002] リンクされた ODBC テーブルで"#Deleted"エラー発生

この記事は、以前は次の ID で公開されていました: JP128809
この資料は、アーカイブされました。これは "現状のまま" で提供され、更新されることはありません。
概要
この資料は、ODBC リンク テーブル内のレコードが "#Deleted" と表示される現象について説明しています。
現象
リンクされている ODBC テーブル内のレコードを取得、挿入、更新する際に、レコード内の各フィールド内に "#Deleted" (Access 2.0 では、"#削除") が表示されます。コードを使用してレコードを取得、挿入、更新する際に、"レコードは削除されます" というエラー メッセージが表示されます。
原因
Microsoft Jet データベース エンジンは、キーセットドリブン モデルを基にデザインされています。データは、キーの値 (リンクされた ODBC テーブルの場合は、テーブルの一意のインデックス) に基づいてデータが取得、挿入、更新されます。

Access は、リンクされた ODBC テーブルの挿入または更新を行ってから、Where 条件を使用して再度レコードを選択し、挿入または更新を確認します。Where 条件は一意のインデックスに基づいています。選択がレコードを何も返さない原因には多くの要素が考えられますが、多くの場合、原因は、Access がキャッシュしているキー値が ODBC テーブル上の実際のキー値と同じでないということです。他に考えられる原因として、以下のようなものがあります。
  • テーブル上に、キー値を変更する更新または挿入のトリガがある。
  • 一意のインデックスが浮動小数点型に基づいている。
  • サーバー上で正しい容量のスペースの埋め込みが行われる可能性のある固定長テキスト フィールドを使用している。
  • 一意のインデックスを構成しているフィールド内に Null 値を含む、リンクされた ODBC テーブルを持っている。
これらの要素は、"#Deleted" と表示される直接の原因となるわけではありません。上記のような場合、Access はキー値維持の次の手順に進み、次にレコード内のその他すべてのフィールドに基づいた条件でレコードを選択します。この手順で複数のレコードが返された場合、Access は、信頼できるキー値がないため、"#Deleted" エラーを返します。テーブルを閉じ、再度開くか、[レコード] メニューから [全レコードの表示] を選択すると、"#Deleted" エラーは削除されます。

Access は同様のプロセスを使用してリンクされた ODBC テーブルからレコードを取得します。まず、キー値を、次にそのキー値に当てはまる残りのフィールドを、取得します。Access は、残りのレコードを探そうとしたときにその値を再度見つけることができない場合、レコードが削除されているとみなします。
状況
この現象は Access の仕様に基づく動作です。
解決方法
この動作を回避するために使用できる方法の一部を以下に示します。
  • 一意のインデックスを除き、まったく同じレコードの入力を避ける。
  • 一意のインデックスと他のフィールドの両方の更新を誘発する更新を避ける。
  • [浮動小数点型] フィールドを一意のインデックスまたは一意のインデックスの一部として使用しない (このデータ タイプに固有の丸めの問題を防ぐため)。
  • すべての更新や挿入を SQL パススルー クエリーを使用して行い、ODBC データ ソースに送信される内容をすべて把握できるようにする。
  • SQL パススルー クエリーを使用してレコードを取得する。SQL パススルー クエリーは更新不可能であるため、"#Deleted" エラーを引き起こしません。
  • リンクされている ODBC テーブルの一意のインデックスを構成しているフィールド内に Null 値を保存しないようにする。

詳細

再現手順

  1. SQL Server のクエリ アナライザ (SQL Server 6.5 以前では iSQL/w) を起動します。
  2. ユーザー "sa" でログインし、"pubs" データベースに接続します。
  3. 以下の SQL スクリプトを実行し、SQL Server 上にテーブルを作成します。
         CREATE DEFAULT dbo.UW_ZeroDefault AS 0     GO     CREATE TABLE 運送会社 (          運送コード int NULL ,          運送会社 varchar (10) NULL)     GO      CREATE  UNIQUE  CLUSTERED  INDEX PK_運送コード ON 運送会社 (運送コード)     GO     EXEC sp_bindefault 'UW_ZeroDefault', '運送会社.運送コード'     GO     CREATE TRIGGER 運送会社_挿入トリガ ON 運送会社 FOR INSERT AS          DECLARE @maxc int, @newc int          SELECT @maxc = (SELECT Max(運送コード) FROM 運送会社)           SELECT @newc = (SELECT 運送コード FROM inserted)           IF @newc = 0 OR @maxc <> @newc SELECT @maxc = @maxc + 1           UPDATE 運送会社 SET 運送コード = @maxc WHERE 運送コード = @newc     GO     INSERT 運送会社 VALUES(1,'ネコ')     INSERT 運送会社 VALUES(2,'トマト')     INSERT 運送会社 VALUES(3,'ペンギン')
  4. Access から ODBC を経由して、SQL Server 上の [運送会社] テーブルをリンクします。
  5. リンクされている [運送会社] テーブルを開き、新規のレコードを入力します。入力するレコードの [会社名] フィールドのデータが前のレコードと同じであることを確認してください。
  6. Tab キーを押して新規のレコードに移動します。入力したレコードに "#Deleted" と表示されています。
  7. テーブルを閉じて、再度テーブルを開きます。レコードの値が正く表示されています。

注意 : Access 2.0 では、リンク テーブルはアタッチ テーブルと呼ばれていました。
関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 128809 (最終更新日 2000-08-09) をもとに作成したものです。

pounddeleted mcsys7 kbinterop kb3rdparty
プロパティ

文書番号:128809 - 最終更新日: 12/04/2015 11:14:30 - リビジョン: 4.0

Microsoft Access 97 Standard Edition, Microsoft Access 95 Standard Edition, Microsoft Access 2.0 Standard Edition

  • kbnosurvey kbarchive # 7.0 8.0 acc10 acc2000 acc95 acc97 accxp deleted kbinfo linked odbc table xp アタッチテーブル リンク 一意 削除 KB128809
フィードバック