原因不明。仕様? バグ?
成果物
期待値
insert
するときid
を省略したい。自動的にrowid
を入れて欲しい。
問題
型int
とするとid
値にNULL
が自動挿入される。
create table t1(id int primary key, name text); insert into t1(name) values('A');
select * from t1;
|A
select * from t1 where id is NULL;
|A
重複エラーにもならない!
主キーとして機能せず……。
insert into t1(name) values('B'); insert into t1(name) values('C'); insert into t1(name) values('D');
select * from t1;
|A |B |C |D
select * from t1 where id is NULL;
|A |B |C |D
これはひどい。integer
をint
にしてinsert
時に省略しただけで、こんな悲劇が起ころうとは一体だれが想像しただろうか。これを仕様というならもう何も信じられないレベル。もはやイントでなくインポ。不能としか言いようがない。
解決
型をint
でなくinteger
にする。
create table t2(id integer primary key, name text); insert into t2(name) values('A');
select * from t2;
1|A
select * from t2 where id is NULL;
現状まとめ
型 | 省略時の値 |
---|---|
int |
NULL |
integer |
rowid |
なぜ?
不明。先述のような違いが生まれる理由は見つけられなかった。
int
でもinteger
と同じではないのか?
宣言されたタイプに
int
が含まれている場合、INTEGER
アフィニティーが割り当てられます。
ならint
でもinteger
と同じ動作になるのでは?
主キーにNULLが含まれることがある
プライマリキーの列値はNULLにできます。これはバグですが、問題が発見された時点で、バグに依存している多くのデータベースがバグに依存していたため、前進するバグの動作をサポートする決定が下されました。
そもそもこのバグ仕様が悪い。これが一因のはず。
こうするとどうなる?
エラーになるパターン集。
not null
制約
create table t1(id int not null primary key, name text); insert into t1(name) values('A');
Error: near line 2: NOT NULL constraint failed: t1.id
insert
するときにid
を省略できなくなる。
default(rowid)
create table t1(id int not null primary key default(rowid), name text);
Error: near line 1: default value of column [id] is not constant
default
値は定数でないとダメらしい。
所感
これもバグ? わからんがint
でなくinteger
にしたほうが良い。int
はタイポでインポなかんぽ。詐欺乙。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13
- bash 4.4.12(1)-release
- SQLite 3.29.0
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux
前回まで
- SQLite3学習をはじめよう
- SQLite3学習 SQLiteについて
- SQLite3学習 SQLiteの適切な用途
- SQLite3学習 SQLiteの特徴
- SQLite3学習 SQLiteのクセ
- SQLite3学習 データ型とアフィニティ
- SQLite3学習 演算子の一覧
- SQLite3学習 よくある質問
- SQLite3学習 SQLiteダウンロード&コンパイル
- SQLite3学習 Tclで操作する
- SQLite3学習 ビルドオプション動作確認(SQLITE_ALLOW_URI_AUTHORITY)
- SQLite3学習 面白そうなコンパイルオプション
- SQLite3学習 SQLiteの拡張について
- SQLite3学習 JSON拡張
- SQLite3学習 JSON拡張(json_extract)
- SQLite3学習 JSON拡張(json_each)
- SQLite3学習 JSON拡張(json_tree オブジェクト→行)
- SQLite3学習 JSON拡張(json_tree オブジェクトツリー→行)
- SQLite3学習 JSON拡張(json_tree オブジェクト配列→行)
- SQLite3学習 JSON拡張(json_group_array 行→配列)
- SQLite3学習 JSON拡張(json_group_object 行→オブジェクト)
- SQLite3学習 JSON拡張(json_array_length)
- SQLite3学習 JSON拡張(json_type)
- SQLite3学習 JSON拡張(json_valid)
- SQLite3学習 JSON拡張(json_quote)
- SQLite3学習 JSON拡張(json_array)
- SQLite3学習 JSON拡張(json_object)
- SQLite3学習 JSON拡張(json_patch)
- SQLite3学習 JSON拡張(json_insert)
- SQLite3学習 JSON拡張(json_replace)
- SQLite3学習 JSON拡張(json_set)
- SQLite3学習 JSON拡張(json_remove)
- SQLite3学習 全文検索(FTS5)
- SQLite3学習 全文検索FTSを日本語で使う方法を調べてみた
- 形態素解析MeCabをインストールする
- SQLite3学習 全文検索FTS5のMeCab用トークナイザを実装する
- SQLite3学習 FTS5+MeCabでクエリ構文
- SQLite3学習 FTS5のテーブル作成と初期化
- SQLite3学習 FTS5の補助関数
- SQLite3学習 FTS5のfts5vocab仮想テーブル
- SQLite3学習 再帰クエリ(WITH RECURSIVE)
- SQLite3学習 R-Treeモジュール
- SQLite3学習 ファイル入出力(SQL集計)
- SQLite3学習 拡張関数(generate_series)