やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

SQLite3構文 alter(add column)概要

 制限つきだが列を追加できる。

成果物

情報源

制限

 SQLite3のalter tableの列操作は他のDBMSに比べると低機能。列の追加に制約があったり、追加以外に変更や削除ができない。

要素/操作 追加 削除
制約

 変更は名前だけ可。renameで。制約は不可。

add column制限

  • 付与不可
    • primary key, unique制約
    • default制約の値にCURRENT_TIME, CURRENT_DATE, CURRENT_TIMESTAMP, 式()
  • not null制約があるときnull以外の値をdefaultに設定する必要がある
  • foreign key references制約を追加したらdefaultnullを設定する必要がある
  • check制約を追加しても既存の行に対してはチェックしない(将来変更される?)

sqlite_master

 alter tablesqlite_masterテーブルのsql列にあるSQLテキストを変更することで機能する。

 このため実行時間はデータ量に依存しない。1行でも1000万行でも同じ。

 これって、sqlite_mastersql列テキストを変更したら構造も反映されるってことか? alter構文を使わずとも? 要検証。

後方互換

 alter tableを実行すると、SQLite3 3.1.3以前では読み込めなくなる。

他の変更をする方法

正解間違い
  1. 新しいテーブルを作成
  2. データをコピーする
  3. 古いテーブルをドロップ
  4. 新しい名前を古い名前に変更
  1. 古いテーブルの名前を変更する
  2. 新しいテーブルを作成
  3. データをコピーする
  4. 古いテーブルをドロップ

 間違った方法でやると以下のリンクが破壊されてしまう。

  • 外部制約
  • ビュー
  • トリガー

 他にも細かい手順が書いてあった。要検証。

やってみる

 ターミナルで以下コマンド実行。

sqlite3

 まずは列を追加するベースとなるテーブルを作る。

create table T(A text);

 定義内容を確認する。

select sql from sqlite_master;
CREATE TABLE T(A text)

 以下の部分が勝手に変更されているが、まあいい。

  • create tableが大文字化
  • 末尾;消失

列の追加

alter table T add column B text;

 確認。

select sql from sqlite_master;
CREATE TABLE T(A text, B text)

 B列が追加された。

追加された既存レコードの列値はNULLである

 テーブル作成からやり直す。既存レコードを作る。

drop table T;
create table T(A text);
insert into T values('AAA');

 列を追加する。

alter table T add column B text;

 既存レコードのうち追加したB列の値はNULLである。

.headers on
select * from T where B is NULL;
A|B
AAA|

 空文字列ではない。

select * from T where B = '';



次回

  1. add column制限の確認
  2. sqlite_mastersql列テキストを変更したら構造も反映されるか確認
  3. 制限を回避した再作成

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux

前回まで