Accessのリンクテーブルで特定の列が#Deletedと表示される
Accessはほとんど使わないので、どういう事象なのかまったくわからない
調べてみると、原因となる可能性が多すぎる…
今回は解決できた(2023/12/15)
環境
Windows 10
Microsoft Access(Office 2016)
SQL Server 14.0.1000.169
起こった事象
AccessのリンクテーブルでSQL Serverのテーブルを参照すると特定の列が#Deletedで表示されるようになった
同名のテーブルで以前は正常に表示されていた、あるときを境に#Deletedになった
正常パターンとエラーパターン
1. 正常に見れていたとき
初めにSQL Serverで作ったテーブル
code:sql
create table #SAMPLE(
id int,
name nvarchar(8),
created_at datetime2,
PRIMARY KEY(id)
);
select * from #SAMPLE;で問い合わせると正常に取得できる
table:result
id name created_at
1 hoge 2023-12-01...
このテーブルにAccessからODBC経由でリンクテーブルを作成すると、正常に全レコードが表示される
table:access
id name created_at
1 hoge 2023-12-01...
ここまではOK
2. Accessで#Deletedになったとき
テーブルの主キーをidのみからidとcreated_atに変更した(dropしてcreateしなおした)
code:sql
create table #SAMPLE(
id int,
name nvarchar(8),
created_at datetime2,
PRIMARY KEY(id, created_at)
);
select * from #SAMPLE;の問い合わせると、変更前と変わらず正しく取得できる
table:result
id name created_at
1 hoge 2023-12-01...
このテーブルにAccessからODBC経由でリンクテーブルを作成すると、created_at列がすべて#Deletedになった
table:access
id name created_at
1 hoge #Deleted
原因と考えられるもの
公式ドキュメントによると、日付(datetime, datetime2)まわりが怪しい
症状
1つ以上のdatetime列またはdatetime2列を含み、Microsoft SQL Serverデータベースに接続され、互換性レベルが130以上(SQL Server 2016の互換性レベル)のMicrosoft Accessにリンクされたテーブルは、結果の#Deletedを返します。
原因
この問題は、datetime列またはdatetime2列に秒の小数部の値が含まれているために発生します。Microsoft SQL Server 2016以降、datetime2型に対する秒の小数部の処理方法が変更されました。変更の詳細については、次の記事を参照してください。(略)
注意
SQL Server ODBCドライバーは、データをサーバーに送信するときにdatetimeをdatetime2に変換するため、datetimeデータ型もdatetime2への変更の影響を受けます。
リンクされたテーブルにアクセスSQL Serverデータベースから "#Deleted" が返されます - Microsoft 365 Apps | Microsoft Learn
解決策
新しめのバージョンのAccessならdatetime2を有効するためにDate Time Extendedを有効にするという方法があるらしい
これが無理なら以下のような回避策がある
1. SQL Serverデータベースの互換性レベルを120(SQL Server 2014の互換性レベル)以下に変更します。
2. datetime列とdateTime2列が主キーの一部ではないことを確認します。
3. タイムスタンプまたはrowversionデータ型を使用して、テーブルに新しい列を追加します。
4. UPDATEステートメントを使用して、datetime列から秒の小数部を削除します。
5. データ型をdatetimeからsmalldatetimeに変更します。注:これにより、値が最も近い分に丸められます。
6. データを編集する必要がない場合は、クエリを作成し、RecordsetTypeプロパティをSnapshotに変更して、この問題の影響を受けない読み取り専用レコードセットを返します。
解決方法 - リンクされたテーブルにアクセスSQL Serverデータベースから "#Deleted" が返されます - Microsoft 365 Apps | Microsoft Learn
2.は今回変更した内容「datetimeを主キーにしたAccessのリンクテーブルで特定の列が#Deletedと表示される#657bb8bbf458200000179306」そのものっぽい
ということでcreated_at以外を主キーに使うことで#Deletedにならなくなった
2.以外の解決方法はリスクちょっと高い…
今回は解決したが…
調べていると、日付以外でもBigint型の列があると起こり得るという事象があった
特定の項目のみ#Deletedと表示される - Microsoftコミュニティ
sql server - Rows showing as #DELETED - Stack Overflow
MS Accessからのクエリで取得されるデータ項目値が全て"#Deleted"と表示される場合の対処方法 | InterSystems
Accessでテーブルにリンクすると、データがすべて"#Deleted"と表示される。 #SQLServer - Qiita
#Deleted in linked ODBC SQL Server tables in Microsoft Access V2205. - Codekabinett
にわか管理者のあてにならん情報: Access から ODBC で SQLServer に接続したら全部 #Deleted と返ってきた
Bigintは使っていなかったので検索対象から外していたんだけど、これも#Deletedになるっぽい
環境としてはOffice 2016頃が多いみたい
これも最新なら解決しているのかな?