SQLiteはスタンドアロン型のオープンソースRDBMSです。
Oracleなどのサーバーアプリケーションとして動作するものと異なり、
SQLiteは各データベースがファイルシステム上のファイルに対応し、
データを扱うアプリケーションの起動と同時にオープンされます。
つまり、MicrosoftのAccessに近いイメージです。
SQLiteはバージョン2から3になるときに大きく仕様が変わりました。
このページでは全てバージョン3の使用方法を説明しています。
今はバージョン3が定着したため、SQLiteといえばSQLite3を指すことがほとんどです。
SQLiteのホームページから、
「Download」を押してダウンロードページに行きます。
「Precompiled Binaries For Windows」の「sqlite-tools-***.zip」
をダウンロードして展開すると、sqlite3.exe などのファイルがあるので、
これを適当な場所に配置すればインストール完了です。
これが、コマンドラインツール(OracleのSQL*Plusみたいなもの)です。
コマンドラインツール sqlite3.exe の典型的な起動方法は
D:\work> C:\Wintools\sqlite3\sqlite3.exe D:\the\path\of\testdb
SQLite version 3.38.1 2022-03-12 13:37:29
Enter ".help" for usage hints.
sqlite> create table shiten
...> (shiten_code varchar(5) primary key,
...> shiten_name varchar(20),
...> area_code varchar(1),
...> address varchar(200),
...> employee_num int);
こんな感じで、引数としてデータベースファイルのパスを指定します
(存在していなければ自動的に作られます)。
データベースファイルの命名は自由なようで、拡張子は特につけないのが慣習のようです。
上にメッセージが出ているように、".help"とタイプすれば、コマンドの一覧が出てきます。
テーブルの一覧を表示にするには ".tables" と入力します。
テーブル定義を表示するには、".schema {テーブル名}" と入力します。
sqlite> .tables
sqlite> .schema ITEMS
ツールを終了するには、".exit"または".quit"と入力します。
バッチ処理的にスクリプトを読ませることもできます。
sqlite3プログラムでは3つの方法が用意されています。
1つはあらかじめ一群のコマンドを順番に書いたスクリプトファイルを、
標準入力からリダイレクトして読ませる方法。
もう1つは sqlite3.exe の2番目の引数を指定すれば、
それがSQLとして解釈実行されるというものです。
3番目は、sqlite3.exeを起動した後「.read {ファイル名}」コマンドで実行する方法です。
(.loadではなく.readなので要注意!!.loadは別のコマンドです。)
●SQLスクリプトのコメント
コメントはC言語式の /* コメント */ と、Oracle式の「--」が両方使えます。
コマンドラインツールといえばデータのインポート。SQLiteでは「.import ファイル名 テーブル名」で可能です。
sqlite> .import .\\area.txt AREA
Windowsの場合の注意点が1つ。パスを指定する際には、パス区切りは普通のスラッシュ1つ(/)にするか、
またはバックスラッシュなら二重(\\)にする必要があります。
またタブ区切り形式で読ませる場合は、そのまま実行すると「line 1: expected {M} columns of data but found {N}」
というエラーになり、区切りが正しく解釈されていないことが分かります。
SQLiteでは事前に.separatorコマンドで、区切り文字を変更できます。
でタブ文字の場合はどう指定すればいいの?「\t」(←見えているまま)とタイプすればOKです。
sqlite> .separator \t
sqlite> .import .\\area.txt AREA
なお、データの1行目に列名の見出しを入れておく必要はありません。
その代わりに、データの並び順はその表のCREATE TABLE文の列の並び順に合わせておく必要があります。
ここはHSQLDBとは異なる点です。
それと別に「.mode csv」か「.mode tabs」(タブ区切り)にして、
データファイルの1行目の各フィールドを列名にして読ませると、
「テーブルを作りつつデータをインポート」させることもできます。
sqlite> .mode csv
sqlite> .import .\\area2.csv AREA2
で、事前に存在していないAREA2テーブルが作られ、データが中に入ります。
ただし、この時全ての列のデータ型は自動的にTEXTになります。
日本語データは、シフトJISでもUTF-8でも一応データベースにロードすることはできます。
ただし公式にサポートされているのはUTF-8(UTF-8N)だけなので、それに統一するのが良いと思います。
ちなみに古いSQLite3のバージョンでは、内部データをUTF-8で格納すると、
Windowsのコマンドプロンプトからsqlite3.exeを実行して検索などを行うと、
日本語は文字化けしていたため、「chcp 65001」と打ってUTF-8に変更する必要がありました。
現在のバージョンでは、内部データがUTF-8でもコマンドプロンプトではシフトJISに自動変換されて表示されます。
また、古いsqlite3.exeのCUIでは、WHERE句に日本語を入力すると正しい結果が得られませんでした
(シフトJISでも、UTF-8でも)。現在は、日本語も入力できます。
表の列定義に使えるデータ型はTEXT、INTEGER、REAL、NUMERIC、BLOBの5種類です。
他のRDBMSや標準SQL92で使われるデータ型名の多くは、
上記のどれかの別名として有効なので、違和感なくSQLを書くことができるでしょう。
例えばINT、TINYINT、SMALLINT、INT8などは、全てINTEGERの別名です。
PostgreSQLなどと同じですね。
VARCHAR、NCHAR、NVARCHAR、CLOBなどは、全てTEXTの別名です。
こちらはOracle、Microsoft SQL Serverなどでおなじみのデータ型ですね。
またFLOATとDOUBLEはREALの別名です。
そして、DECIMAL、BOOLEAN、DATE、DATETIMEは、内部的にはNUMERICの別名として処理されています。
SQLiteにも多くの組み込み関数があり、その中に現在時刻を返すものも用意されています。
テーブルの列定義でDEFAULT値として現在時刻を設定するには次のようにします。
CDATE DATE NOT NULL DEFAULT (DATETIME('now','localtime'))
DATETIMEは括弧で囲む必要があります。
囲まないと1行目にsyntax errorがある、と表示されます。
なお、DEFAULT句を上のように設定しても、
sqlite3.exeで
としたとき、自動で日時は設定されないらしいです。
UPDATE ITEMS SET CDATE=DATETIME('now','localtime')
と自分で設定する必要があるようです。
●日付だけを返す(時分秒は0)
DATETIME関数の代わりにDATE関数を使うと、時分秒の部分が全て0の日付だけのデータを取得できます。
UPDATE ITEMS SET CDATE=DATE('now','localtime')
●N日前などの日付の取得
次のように引数を増やすと、N日前、N日後などの日付を取得できます。
例えば下の例では今日の7日後の日付を設定しています。
UPDATE ITEMS SET CDATE=DATE('now','+7 day','localtime')
| 自動的に増える整数列(AUTOINCREMENT) |
SQLiteにはシーケンスがありません。
行を追加するたび値が自動的に1ずつ増えていく主キー列を定義するには、
PRIMARY KEYとAUTOINCREMENTを両方指定したキーを定義します。
CREATE TABLE ITEMS (
ITEM_ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
ITEM_NAME VARCHAR(30) NOT NULL,
UOM VARCHAR(3) NOT NULL DEFAULT 'PCS',
CDATE DATE DEFAULT (DATETIME('now','localtime'))
);
ただしこの系統の主キー列を持つテーブルには、.importコマンドでデータをロードできません。
データファイルから主キー列を外しても、空の列を作ってもどちらもエラーになります。
現実的な方法は次のようにロード用のテーブルを用意して、
それに読んでからINSERT-SELECTでコピーする方法です。
CREATE TABLE ITEMS_IF (
ITEM_NAME VARCHAR(30) NOT NULL,
UOM VARCHAR(3) NOT NULL DEFAULT 'PCS'
);
-- .import コマンドでITEMS_IFテーブルにデータをロードする
INSERT INTO ITEMS(ITEM_NAME, UOM) SELECT ITEM_NAME, UOM FROM ITEMS_IF;
なおINSERT-SELECTのSELECTの部分を括弧で囲む必要はありません。
他のRDBMSとは違うので要注意ですね。
テーブルのデータをCSVやタブ区切りなどの形式でファイルに出力できます。
.headers on(またはoff)
.mode tabs
.output ./export.txt
SELECT * FROM ITEMS
.output stdout
.mode tabsはタブ区切りを指定しています。csvだとCSVになります。
一方、今テーブルに入っているデータを完全に復元するための
CREATE TABLE文やINSERT文を順番に出力することもできます。
これは.dumpコマンドで可能で、出力したファイルを.readすれば元のテーブルが復元できます。
.separator \t
.output ./dump.txt
.dump items
.output stdout
なお、新しいバージョンでは
.outputを次の1回分だけ適用する.onceというコマンドもあるようです。
●attempt to write a readonly database
実行ユーザーにデータベースファイルへの書き込み権限を付けているのに、
このエラーが発生することがあります。
ネット情報によると原因は幾つかあるようですが、
私がはまったのはデータベースのファイルを置いてある「ディレクトリ自身」にも書き込み権限が必要なことです。
対応するとあっさり解決しました。
SELECT GROUP_CONCAT(NAME, ',') FROM PRAGMA_TABLE_INFO('ITEMS');
とすると、ITEMSテーブルの各列名をカンマ区切りで出力できます。
SELECT 'a.' || GROUP_CONCAT(NAME, ',a.') FROM PRAGMA_TABLE_INFO('ITEMS');
とすると、テーブル識別子a.を付与した列の一覧を出力できるため、
これを切り貼りするだけで複数のテーブルをJOINするSQLなどを簡単に作成できます。
SQLiteはFOREIGN KEYをサポートしています(使っても文法エラーにはならない)が、
実際のチェックは効いていません。実際に、違反したデータが登録できてしまいます。
SQLiteにはOracleのようなCREATE OR REPLACE文はありませんが、
代わりにINSERT OR REPLACEという文があります。
こちらに例が載っています。
これは結構便利。
また、SQLiteにはIFNULLという、OracleのNVLに当たる関数があります。これも便利です。
|
|
|
もくじ
|
|
SQLite
|
|
(C) 2002-2025 MISUMI URANO (2006/01/29 - 2026/09/09)
|