search
LoginSignup
2

More than 5 years have passed since last update.

posted at

sqlite3のblob操作API

sqlite3でcからblobを操作してみた。
(とりあえずエラーは考えないことにして)

#include <stdio.h>
#include <sqlite3.h>

int main(int argc, char** argv) {
    sqlite3* dp = NULL;
    sqlite3_stmt *pStmt = NULL;
    char hash[4] = {1, 3, 5, 7};
    int ok;

    sqlite3_open(":memory:", &dp);

    sqlite3_exec(dp, "CREATE TABLE TESTTBL(NAME VARCHAR PRIMARY KEY, HASH BLOB);", NULL, NULL, NULL);

    sqlite3_prepare_v2(dp, "INSERT INTO TESTTBL (NAME, HASH) VALUES ($1, $2);", -1, &pStmt, NULL);
    sqlite3_bind_text(pStmt, 1, "Bob", -1, SQLITE_STATIC);
    sqlite3_bind_blob(pStmt, 2, hash, 4, SQLITE_STATIC);
    //sqlite3_bind_blob(pStmt, 2, hash, 4, SQLITE_TRANSIENT);
    //hash[0] = 2;
    sqlite3_step(pStmt);
    //hash[1] = 4;
    sqlite3_finalize(pStmt);

    sqlite3_prepare_v2(dp, "SELECT NAME, HASH FROM TESTTBL;", -1, &pStmt, NULL);
    while (sqlite3_step(pStmt) == SQLITE_ROW){
        const unsigned char *name = sqlite3_column_text(pStmt, 0);
        int size = sqlite3_column_bytes(pStmt, 1);
        char * b = (char *)sqlite3_column_blob(pStmt, 1);
        printf("name: %s, hash:", name);
        for (int i = 0; i < size; ++i) {
            printf(" %x", b[i]);
        }
        printf("\n");
    }
    sqlite3_finalize(pStmt);

    sqlite3_close(dp);

    return 0;
}

sqlite3_bind...のカラムは1から始まるけど、sqlite3_column...のカラムは0から。

SQLITE_STATICの場合、hash[0] = 2;は結果に影響するけどhash[1] = 4;は影響しない。
つまりsqlite3_step()が終わるまではblobのメモリを維持しなきゃいけない模様。
何も考えずにSQLITE_TRANSIENTにしても普通は問題無いかも。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2