揮発性のメモ2

http://d.hatena.ne.jp/iww/

sqlite3のエラー処理

http://www.3rd-impact.net/Document/SQLite/Translation/Current/capi3ref.html#sqlite3_finalize

すべての構築済みステートメントは、sqlite3_close() を呼ぶ前に、あるいは SQLITE_BUSY の戻り値で失敗して閉じる時に削除しなくてはいけません。

ステートメントが開放されてないときにsqlite3_close()を呼ぶとエラーSQLITE_BUSYが返ってデータベースが閉じられない。
(放置すると「ファイルディスクリプタいっぱいでもう開けませんエラー EMFILE」で困ることになる)

    // データベースを開くのに失敗しても、データベースを閉じる
    result = sqlite3_open( DBFILE, &db);
    if( result!=SQLITE_OK ){
        sqlite3_close(db);
        return -1;
    }

    // prepareが失敗したときは、ステートメントは開放しなくていい
    sql = "SELECT hoge,fuga FROM piyo LIMIT 1";
    result = sqlite3_prepare( db, sql, strlen(sql), &stmt, NULL);
    if( result!=SQLITE_OK ){
        sqlite3_finalize(stmt); // ←しなくてもいいけど、しても別に文句は言われない
        sqlite3_close(db);
        return -1;
    }

    // ここから下にはステートメントが存在する

    // 実行
    result = sqlite3_step(stmt);
    if( result==SQLITE_DONE ){
        // データはなかった
    }else if( result==SQLITE_ROW ){
        // データはあったので取り出して処理とかする
    }else{
        // エラーだった
    }

    // ステートメントを開放してからデータベースを閉じる
    sqlite3_finalize(stmt);
    sqlite3_close(db);

ステートメントがNULLでも別にエラーにはならないので、面倒だからもう、 sqlite3_finalize(stmt); sqlite3_close(db); は常にワンセットでもいいくらい。書き忘れてバグになるよりはマシ。