2012-10-20 54 views
2

我用SQLite卡在作業上。我使用2列;第一個產品,第二個產品。用戶添加新產品,更新計數。我們必須控制,用戶不再添加相同的產品,或防止他挑選比可用的單位更多的單位。我們必須經常使用它,所以我創建功能:SQLite:錯誤的sqlite3_prepare_v2調用 - > SIGSEGV

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

對不起,我的英語我來自捷克。

回答

0

sqlite3_prepare_v2想要將語句指針寫入您的輸出變量,但是您沒有給它一個指向此指針變量的指針,您正在給它指定一個NULL指針。 用途:

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

另外請注意,標識應與"double quotes"[brackets]

`backticks` 

但與'single quotes',這是用於文字字符串被引用。

+0

謝謝, 我必須改變返回'strcmp(a,param);'也是, - 如果== null,它會崩潰。 – Bender250

+0

你忘記了調用['sqlite3_step'](http://www.sqlite.org/c3ref/step.html)。 「SQLITE_ROW」和「SQLITE_DONE」之間的區別允許你檢測你是否有一條記錄,而不必閱讀某一列。 –