CodeZine(コードジン)

特集ページ一覧

SQLiteで“おこづかいちょう”

SQLite、C++/CLI、C#で実用(?)アプリケーションを作る

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/05/14 14:00
目次

結果の取得とUnicode

クエリ結果の取得

 SQL文がSELECTのように複数(0個以上)の結果を返すとき、sqlite3_step()を何度も呼び出すことでその結果が得られます。

 sqlite3_step()は結果の個数だけSQLITE_ROW、そして最後にSQLITE_DONEを返します。結果の取得は、

  • const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
  • double sqlite3_column_double(sqlite3_stmt*, int iCol);
  • int sqlite3_column_int(sqlite3_stmt*, int iCol);
  • sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
  • const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);

 にステートメント・ハンドルとカラム位置(0起点)を与えることで得られます。

九九の表から五の段を検索する
sqlite3_stmt* statement;
const char* command = "SELECT * FROM mul_table WHERE x = 5;"
sqlite3_prepare_v2(db, command, -1, &statement, 0);
while ( sqlite3_step(statement) == SQLITE_ROW ) {
  int x = sqlite3_column_int(statement,0);
  int y = sqlite3_column_int(statement,1);
  int z = sqlite3_column_int(statement,2);
  cout << x << '*' << y << '=' << z << endl; 
}

Unicodeの扱い

 SQLiteで扱う文字はUTF-8もしくはUTF-16となっており、ここまでの説明はUTF-8のものです。文字コードをUTF-16とする関数にはsqlite3_column_text16()のように末尾に16がつけられています。このとき、文字列を表す型はchar*ではなくvoid* です。wchar_t*ではないことに注意してください(SQLiteはwchar_t型をサポートしない処理系を考慮してvoid*を使っているのでしょう)。

 まとめとして、SQLiteの主要APIを使ったUTF-16(Unicode)版サンプルコードを示します。

Unicode版サンプルコード
/*
 * SQLite のC++によるサンプル(Visual C++)
 *  cl -MD -EHsc -I. trial.cpp sqlite3.lib
 */
 
#include <iostream>  // wcout, endl
#include <string>    // wstring
#include <locale>    // locale
#include <sqlite3.h> // SQLite3

struct Record {
  wchar_t* shop;
  wchar_t* dish;
  int      price;
  double   score;
};

using namespace std;

typedef const wchar_t* cwp;

int main() {

  /*
   * Unicode出力のためのlocale設定
   */
  wcout.imbue(locale("japanese"));

  sqlite3* db;
  int result;

  /*
   * データベースのオープン 
   */
  sqlite3_open16(L"trial.db", &db);

  sqlite3_stmt* statement;
  const void* command;

  /*
   * シングル・ステートメント SQL の実行
   */
  command = L"DROP TABLE IF EXISTS 飯屋";
  sqlite3_prepare16_v2(db, command, -1, &statement, 0);
  sqlite3_step(statement);
  sqlite3_finalize(statement);

  command = L"CREATE TABLE 飯屋 ( 店名 TEXT, 品名 TEXT, 価格 INTEGER, 評価 FLOAT);";
  sqlite3_prepare16_v2(db, command, -1, &statement, 0);
  sqlite3_step(statement);
  sqlite3_finalize(statement);

  /*
   * マルチ・ステートメント SQL の実行
   */
  command = L"INSERT INTO 飯屋 VALUES ( '蓬莱', 'ラーメン', 500, 2.5 );"
            L"INSERT INTO 飯屋 VALUES ( '崑崙', 'ラーメン', 550, 3.0 )";
  while ( *static_cast<cwp>(command) ) {
    sqlite3_prepare16_v2(db, command, -1, &statement, &command);
    result = sqlite3_step(statement);
    sqlite3_finalize(statement);
  }

  /*
   * パラメータのバインド
   */
  Record data[] = {
    { L"来来軒",   L"ラーメン",   600, 3.0 },
    { L"来来軒",   L"チャーハン", 500, 4.5 },
    { L"来来軒",   L"ニラレバ",   650, 2.0 },
    { L"激旨食堂", L"チャーハン", 500, 4.8 },
    { L"激旨食堂", L"ギョーザ",   350, 3.5 },
    { 0 }
  };

  command = L"INSERT INTO 飯屋 VALUES ( ?, ?, ?, ? )";
  sqlite3_prepare16_v2(db, command, -1, &statement, 0);
  for ( Record* rec = data; rec->shop; ++rec ) {
    sqlite3_reset(statement);
    sqlite3_bind_text16(statement, 1, rec->shop , -1, SQLITE_STATIC);
    sqlite3_bind_text16(statement, 2, rec->dish , -1, SQLITE_STATIC);
    sqlite3_bind_int   (statement, 3, rec->price);
    sqlite3_bind_double(statement, 4, rec->score);
    result = sqlite3_step(statement);
  }
  sqlite3_finalize(statement);

  /*
   * クエリの実行と値の取得
   */
  command = L"SELECT * FROM 飯屋 WHERE 評価 >= 3.0";
  sqlite3_prepare16_v2(db, command, -1, &statement, 0);
  while ( sqlite3_step(statement) == SQLITE_ROW ) {
    wcout << static_cast<cwp>(sqlite3_column_text16(statement,0)) 
          << " | "
          << static_cast<cwp>(sqlite3_column_text16(statement,1)) 
          << " | "
          << sqlite3_column_int   (statement,2) << " | "
          << sqlite3_column_double(statement,3)
          << endl;
  }

  /*
   * データベースのクローズ
   */
  sqlite3_close(db);

}

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • επιστημη(エピステーメー)

    C++に首まで浸かったプログラマ。 Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"り わんくま同盟でたまにセッションスピーカやったり 中国茶淹れてにわか茶人を気取ってたり、 あと Facebook とか。 著書: - STL標準...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5