原因不明。仕様? バグ?
成果物
期待値
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)