ラベル SQLite の投稿を表示しています。 すべての投稿を表示
ラベル SQLite の投稿を表示しています。 すべての投稿を表示

2014年6月29日日曜日

[Python][SQLite]データ登録後 Commit を不要にする

DB を開く時に isolation_level=None を指定することでデータ登録後に Commit を実行する必要がなくなる。
con = sqlite3.connect("data.db", isolation_level=None)

[Python][SQLite]使い方

Python 2.5 から SQLite3 が標準で使えるようになっている。
# -*- coding: utf-8 -*-
import sqlite3

needCommit = 0

# Database を開く
if needCommit == 1:
    con = sqlite3.connect("data.db");
else:
    con = sqlite3.connect("data.db", isolation_level=None); # Commit 不要

# Table 作成
sql = u"CREATE TABLE test(ID INT PRIMARY KEY, NAME TEXT NOT NULL);"
con.execute(sql)

# データ登録
sql = u"INSERT INTO test(ID, NAME) values (0, 'aaa');"
con.execute(sql)

# データ登録 その 2
sql = u"INSERT INTO test(ID, NAME) values (?, ?);"
con.execute(sql, (1, "bbb"))
con.execute(sql, (2, "ccc"))

if needCommit == 1:
    con.commit()

# レコード取得
c = con.cursor()
c.execute("SELECT * FROM test")
for row in c:
    print row[0], row[1]

# Database を閉じる
con.close();
実行結果
> python sqlite.py
0 aaa
1 bbb
2 ccc
各処理を関数化、テーブルが作成済みの場合は最初に drop する処理を追加
# -*- coding: utf-8 -*-
import sqlite3

# Database を開く
def connectDb():
    print "Connect DB"
    con = sqlite3.connect("data.db", isolation_level=None);
    return con

# Table 作成
def createTable(con, name):
    print "Create table";
    sql = "CREATE TABLE %s(ID INT PRIMARY KEY, NAME TEST NOT NULL);" % name
    con.execute(sql)

# データ登録
def addData(con, id, name):
    print "Add data (%d %s)" % (id, name)
    sql = "INSERT INTO test(ID, NAME) values(%d, '%s');" % (id, name)
    print sql;
    con.execute(sql)

# 全レコード表示
def showAllRecord(con):
    c = con.cursor()
    c.execute("SELECT * FROM test")
    for row in c:
        print row[0], row[1]

# Database を閉じる
def closeDb(con):
    print "Close database"
    con.close()

# テーブル一覧表示
def showAllTables(con):
    c = con.cursor()
    c.execute("SELECT NAME FROM sqlite_master WHERE type='table'")
    for row in c:
        print row[0]

# テーブル作成済みか確認
def alreadyCreatedTable(con, name):
    c = con.cursor()
    c.execute("SELECT NAME FROM sqlite_master WHERE type='table'")
    for row in c:
        if row[0] == name:
            print "Found %s" % name;
            return 1
    return 0

# Drop table
def dropTable(con, name):
    print "Drop table %s" % name
    sql = "DROP TABLE %s;" % name
    con.execute(sql)

# メイン処理
con = connectDb()
showAllTables(con)
if alreadyCreatedTable(con, 'test') == 1:
    dropTable(con, 'test')
    createTable(con, 'test')

showAllTables(con)
alreadyCreatedTable(con, 'test')

addData(con, 0, 'aaa')
addData(con, 1, 'bbb')
addData(con, 2, 'ccc')

showAllRecord(con)
closeDb(con)
実行結果
> python sqlite2.py
Connect DB
Create table
test
Found test
Add data (0 aaa)
INSERT INTO test(ID, NAME) values(0, 'aaa');
Add data (1 bbb)
INSERT INTO test(ID, NAME) values(1, 'bbb');
Add data (2 ccc)
INSERT INTO test(ID, NAME) values(2, 'ccc');
0 aaa
1 bbb
2 ccc
Close database

> python sqlite2.py
Connect DB
test
Found test
Drop table test
Create table
test
Found test
Add data (0 aaa)
INSERT INTO test(ID, NAME) values(0, 'aaa');
Add data (1 bbb)
INSERT INTO test(ID, NAME) values(1, 'bbb');
Add data (2 ccc)
INSERT INTO test(ID, NAME) values(2, 'ccc');
0 aaa
1 bbb
2 ccc
Close database

2013年1月27日日曜日

[SQLite][SQL]データの表示方法を変更する

Default 表示
sqlite> SELECT * FROM tbl1;
hello|10
goodbye|20
column モード
sqlite> .mode column
sqlite> SELECT * FROM tbl1;
hello       10
goodbye     20
Header 追加
sqlite> .header on
sqlite> SELECT * FROM tbl1;
one         two
----------  ----------
hello       10
goodbye     20

[SQLite][SQL]コマンドライン操作

sqlite3.exe の引数はデータベースファイル名
> sqlite3.exe ex0.sqlite
SQLite version 3.7.5
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
テーブルを作成してデータを追加、表示まで
sqlite> CREATE TABLE tbl1(one varchar(10), two smallint);
sqlite> INSERT INTO tbl1 VALUES ('hello', 10);
sqlite> INSERT INTO tbl1 VALUES ('goodbye', 20);
sqlite> SELECT * FROM tbl1;
hello|10
goodbye|20
データを絞って表示
sqlite> SELECT * FROM tbl1 WHERE two >= 15;
goodbye|20
終了
sqlite> .exit
DB ファイル内にあるテーブル一覧表示
sqlite> .tables
tbl1  tbl2
参照: Command Line Shell For SQLite

[SQLite][SQL]Date データの扱い

Date データを扱う時は date() 関数を通す。
sqlite> CREATE TABLE tokyoTemperature (id INTEGER NOT NULL PRIMARY KEY, date DATE NOT NULL, ave FLOAT NOT NULL);
sqlite> INSERT INTO tokyoTemperature VALUES (NULL, date('2011-01-01'), 6.6);
sqlite> INSERT INTO tokyoTemperature VALUES (NULL, date('2011-01-02'), 7.0);
sqlite> INSERT INTO tokyoTemperature VALUES (NULL, date('2011-01-03'), 5.9);
sqlite> INSERT INTO tokyoTemperature VALUES (NULL, date('2011-01-04'), 6.3);
sqlite> INSERT INTO tokyoTemperature VALUES (NULL, date('2011-01-05'), 7.3);
sqlite> INSERT INTO tokyoTemperature VALUES (NULL, date('2011-01-06'), 6.5);
sqlite> SELECT * from tokyoTemperature;
id          date        ave
----------  ----------  ----------
1           2011-01-01  6.6
2           2011-01-02  7.0
3           2011-01-03  5.9
4           2011-01-04  6.3
5           2011-01-05  7.3
6           2011-01-06  6.5
sqlite> SELECT * from tokyoTemperature WHERE date >= date('2011-01-05');
id          date        ave
----------  ----------  ----------
5           2011-01-05  7.3
6           2011-01-06  6.5
date() を通さずにデータを登録すると異なる値が入ってしまう。
sqlite> INSERT INTO tokyoTemperature VALUES (NULL, 2011-01-07, 4.0);
sqlite> SELECT * FROM tokyoTemperature WHERE id = 7;
id          date        ave
----------  ----------  ----------
7           2003        4.0
参考: SQLite Query Language: Date And Time Functions

[SQLite][SQL]AUTO INCREMENT

SQLite には AUTO_INCREMENT (AUTOINCREMENT) キーワードが準備されていない。
AUTO INCREMENT を使う場合は "INTEGER NOT NULL PRIMARY KEY" でフィールドを定義して、データ登録の時は NULL を指定する。

実行結果
> a.exe test.db "CREATE TABLE test_tbl(ID INTEGER PRIMARY KEY, NAME TEXT NOT NULL);"
> a.exe test.db "INSERT INTO test_tbl(ID, NAME) VALUES (NULL, '1st');"
> a.exe test.db "INSERT INTO test_tbl(ID, NAME) VALUES (NULL, '2nd');"
> a.exe test.db "INSERT INTO test_tbl(ID, NAME) VALUES (NULL, '3rd');"
> a.exe test.db "SELECT * from test_tbl;"
ID = 1
NAME = 1st

ID = 2
NAME = 2nd

ID = 3
NAME = 3rd

sqlite3.exe の場合
sqlite> CREATE TABLE tbl3 (id INTEGER NOT NULL PRIMARY KEY, name TEXT NOT NULL);
sqlite> INSERT INTO tbl3 VALUES (NULL, 'Tokyo');
sqlite> INSERT INTO tbl3 VALUES (NULL, 'Osaka');
sqlite> INSERT INTO tbl3 VALUES (NULL, 'Nagoya');
sqlite> SELECT * FROM tbl3;
1|Tokyo
2|Osaka
3|Nagoya

[SQLite][SQL]sqlite3_get_table

sqlite3_exec() に callback 関数を登録する以外にテーブルのデータ一覧を取得する方法として sqlite3_get_table() がある
char **azResult;
int row, column;
int i, j;

rc = sqlite3_get_table(db, argv[2], &azResult, &row, &column, &zErrMsg);
if (rc != SQLITE_OK) {
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
    sqlite3_free(zErrMsg);
}
printf("row=%d column=%d\n", row, column);
for (i = 0; i <= row; i++) {
    for (j = 0; j < column; j++) {
        printf("[%d,%d] %s ", i, j, azResult[(i * column + j)]);
    }
    printf("\n");
    if (i == 0) {
        printf("-----------------------------\n");
    }
}
sqlite3_free_table(azResult);
実行結果
row=3 column=2
[0,0] ID [0,1] NAME
-----------------------------
[1,0] 1 [1,1] 1st
[2,0] 2 [2,1] 2nd
[3,0] 3 [3,1] 3rd

[SQLite][SQL]MinGW, MSYS 環境での sqlite のコンパイル・使用方法

  1. sqlite3 の関数を使用するプログラムを準備する。
    main.c
    #include 
    #include "sqlite3.h"
    
    static int callback(void *NotUsed, int argc, char **argv, char **azColName)
    {
        int i;
        for (i = 0; i < argc; i++) {
            printf("%s = %s\n", azColName[i], (argv[i] ? argv[i] : "NULL"));
        }
        printf("\n");
    
        return 0;
    }
    
    // メイン関数
    int main(int argc, char **argv)
    {
        sqlite3 *db;
        int rc;
        char *zErrMsg = 0;
    
        if (argc != 3) {
            fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
            return -1;
        }
    
        rc = sqlite3_open(argv[1], &db);
        if (rc) {
            fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
            sqlite3_close(db);
            return -1;
        }
    
        rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
        if (rc != SQLITE_OK) {
            fprintf(stderr, "SQL error: %s\n", zErrMsg);
            sqlite3_free(zErrMsg);
        }
        sqlite3_close(db);
    
        return 0;
    }
    
  2. Makafile を準備する。
    Makefile
    CC=gcc
    CFLAGS = -Wall
    LDFLAGS = -lsqlite3
    TARGET = \
         main.exe
    
    .SUFFIXES: .exe .c .o
    
    .c.o:
         $(CC) $(CFLAGS) -c -o $@ $<
    
    .o.exe:
     $(CC) -o $@ $< $(LDFLAGS)
    
    default: $(TARGET)
    
    clean:
     rm -rf *.o *.exe
    
  3. コンパイルをする
  4. 実行して動作確認する。第 1 引数はデータベースファイル名、第 2 引数に SQL 文を渡す。
    > a.exe test.db "CREATE TABLE test_tbl(ID INT PRIMARY KEY, NAME TEXT NOT NULL);"
    > a.exe test.db "INSERT INTO test_tbl(ID, NAME) values (0, 'hoge');"
    > a.exe test.db "SELECT * from test_tbl;"
    ID = 0
    NAME = hoge
    
    > a.exe test.db "INSERT INTO test_tbl(ID, NAME) values (1, 'aaa');"
    > a.exe test.db "SELECT * from test_tbl;"
    ID = 0
    NAME = hoge
    
    ID = 1
    NAME = aaa
    

2013年1月26日土曜日

[SQLite][SQL]インストール

Windows 用コンパイル済みバイナリ
SQLite Download Page から Windows 用コンパイル済みバイナリ (sqlite-shell-win32-x86-3070500.zip, sqlite-dll-win32-x86-3070500.zip) をダウンロードする。

MinGW
  1. SQLite Home Page の DOWNLOAD ページにあるソースコード (sqlite-amalgamation-3_6_18.zip, 2009/10/13 現在) をダウンロードする。
  2. ダウンロードしたファイルを展開する。
  3. configure
    > sh ./configure --prefix=/c/usr/MinGW
    
  4. make
    > make
    
  5. ここで下記のような Warning が頻出するが、コンパイルは完了する。
    Temp/ccfFx7ME.s:184210: Warning: .stabn: description field '10d6b' too big, try a different debug format
    
  6. make install
  7. > make install