2

SQLite の宿題で行き詰まっています。私は 2 つの列を使用します。1 番目は製品、2 番目はカウントです。ユーザーが新しい商品を追加すると、カウントが更新されます。ユーザーが同じ製品を再度追加したり、利用可能な数より多くのユニットを選択できないように制御する必要があります。頻繁に使用する必要があるため、関数を作成しました。

int exists(char *param, sqlite3** ppDb) //0 if product exists
{
    int error = 0;
    char *a = NULL;
    sqlite3_stmt **ppStmt = NULL;
    const char **pzTail = NULL;
    char *zSQL = sqlite3_mprintf("SELECT 'products' FROM 'table' WHERE 'products' LIKE '%q'", param);
//HERE IT FALS
    error = sqlite3_prepare_v2(
      *ppDb,                /* Database handle */
      zSQL,                 /* SQL statement, UTF-8 encoded */
      (sizeof(zSQL)+1),         /* Maximum length of zSql in bytes. */
      ppStmt,               /* OUT: Statement handle */
      pzTail                /* OUT: Pointer to unused portion of zSql */
    );
    sqlite3_free(zSQL);
    a = (char*) sqlite3_column_text(*ppStmt, 0);
    return strcmp(a, param); //0 if same -> product is in db yet
}
//similar one for count

電話

int main(int argc, const char *argv[])
{
    sqlite3 *pDb;
    int error = 0;
//parsing input
    error = sqlite3_open(argv[1], &pDb);
    if (error == 0)
    {
        sqlite3_exec(
          pDb,      /* An open database */
          "CREATE TABLE 'table' ('products', 'quantity')",  /* SQL */
          0,        /* Callback function */
          NULL,     /* 1st argument to callback */
          NULL      /* Error msg written here */
        );

        if (exists(param[1], &pDb) == 0) 
        {
            fprintf (stderr, "ERROR: Product exists yet\n");
        }
        else
        {
            char *zSQL = sqlite3_mprintf("INSERT INTO 'table' VALUES ('%q', '0')", param[1]);
            error = sqlite3_exec(
              pDb,      /* An open database */
              zSQL,     /* SQL to be evaluated */
              0,        /* Callback function */
              NULL,     /* 1st argument to callback */
              NULL      /* Error msg written here */
            );
            sqlite3_free(zSQL);
            if (error == 0) printf("Added\n");
            else printf("%i", error);
        }
    }
    else return 1;
    return 0;
}

で失敗しsqlite3_prepare_v2ます。のポインターに問題があると思いますpDbが、修正できませんでした (私はポインターのファンではありません - 初心者には強力なツールです)。失敗すると、デバッガーは sqlite3.c の 93396 行にスタックしました (*ppStmt = 0; - 書き込むべきではない場所に書き込みます)。

Linux x64 でコンパイル:

gcc -std=c99 -Wall -pedantic -Wextra -Werror -DSQLITE_THREADSAFE=0 -ldl -o sqlite main.c sqlite3.c

何も問題はありません (括弧を間違ってコピーした場合は無視してください - それは問題ではありません)、SQLite 3.7.14.1

私の英語でごめんなさい、私はチェコ出身です。

4

1 に答える 1

0

sqlite3_prepare_v2ステートメント ポインターを出力変数に書き込もうとしていますが、このポインター変数へのポインターではなく、ポインターを与えていNULLます。使用する:

sqlite3_stmt *pStmt;
sqlite3_prepare_v2(..., &pStmt, ...);

"double quotes"また、識別子はor[brackets]またはで引用する必要があることに注意してください。

`backticks`

ただし'single quotes'、リテラル文字列に使用される では使用できません。

于 2012-10-20T20:01:50.717 に答える