2021年10月16日土曜日

SQLite3 存在しないファイル名をアタッチすると0Byteのファイルが出来る

概要

ATTACH構文を利用すると複数のデータベースファイルを同時に操作することができるが、 存在しないファイルを指定すると空のファイルが新規作成される。

SQLite3 のデータベースとして操作することが出来るので、 テーブルを作成したり、データを挿入したりすることもできる。
DETACHで切り離しても作成されたファイルは残る。

データベースファイルに接続しつつ、別のデータベースファイルを新規作成する、 というようなことに応用出来るかもしれない。

エラーメッセージや新規作成のメッセージが出ないので、 間違って指定してしまった場合 すぐに気づけないのが難点。

実行例

Attach Attach sample1.db sample1.db sample2.db sample2.db Connect Connect User User Viewer does not support full SVG 1.1
実行環境
  • Windows 10 64bit
  • SQLite3 (3.36.0) Command-Line Shell

C:\temp>rem # 1.
C:\temp>dir
ドライブ C のボリューム ラベルは Windows です
ボリューム シリアル番号は XXXX-XXXX です

C:\temp のディレクトリ

2021/10/14  20:29    <DIR>          .
2021/10/14  20:29    <DIR>          ..
2021/10/14  20:29             8,192 sample1.db
                1 個のファイル               8,192 バイト
                2 個のディレクトリ  61,635,493,888 バイトの空き領域

C:\temp>rem # 2.
C:\temp>sqlite3 sample1.db
SQLite version 3.36.0 2021-06-18 18:36:39
Enter ".help" for usage hints.

sqlite> -- # 3.
sqlite> attach database "./sample2.db" as sub;

sqlite> -- # 4.
sqlite> .databases
main: C:\temp\sample1.db r/w
sub: C:\temp\sample2.db r/w

sqlite> .shell dir
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は xxxx-xxxx です

 C:\temp のディレクトリ

2021/10/17  16:36    <DIR>          .
2021/10/17  16:36    <DIR>          ..
2021/10/14  20:29             8,192 sample1.db
2021/10/14  20:31                 0 sample2.db
               2 個のファイル               8,192 バイト
               2 個のディレクトリ  62,306,549,760 バイトの空き領域

sqlite> -- # 5.
sqlite> create table sub.user
   ...> (
   ...>     id integer
   ...>     , name text
   ...> );
sqlite> insert into sub.user
   ...> values (
   ...>     1
   ...>     , 'test_user'
   ...> );
sqlite> select * from sub.user;
1|test_user

sqlite> -- # 6.
sqlite> detach sub;

sqlite> -- # 7.
sqlite> .open "./sample2.db"
sqlite> .databases
main: C:\temp\sample2.db r/w

sqlite> -- # 8.
sqlite> .tables
user
sqlite> select * from user;
1|test_user
                
  1. 現在のディレクトリにあるのはsample1.dbファイルのみ
  2. sample1.dbに接続
  3. sample2.dbを別名subでアタッチ
  4. 新規にsample2.dbが作成される
  5. sample2.dbにテーブルを作成しデータを挿入
  6. sample2.dbをデタッチ
  7. sample1.dbを切断し、sample2.dbに接続しなおす
  8. 先ほど作成したテーブルの内容が確認できる

参考URL