【问题标题】:SQLite: wrong call of sqlite3_prepare_v2 -> SIGSEGVSQLite:sqlite3_prepare_v2 的错误调用-> SIGSEGV
【发布时间】:2012-10-11 01:46:17
【问题描述】:

我在使用 SQLite 的作业上卡住了。我使用 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

对不起我的英语,我来自捷克。

【问题讨论】:

    标签: c sqlite segmentation-fault


    【解决方案1】:

    sqlite3_prepare_v2 想要将语句指针写入您的输出变量,但您并没有给它一个指向该指针变量的指针,而是给它一个NULL 指针。 使用:

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

    另请注意,标识符应使用"double quotes"[brackets]

    `backticks`
    

    但不适用于'single quotes',后者用于文字字符串。

    【讨论】:

    • 谢谢,我也必须更改 return strcmp(a, param);, - 如果 a == null,它会崩溃。
    • 您忘记致电sqlite3_step。而SQLITE_ROWSQLITE_DONE 之间的区别让您无需阅读某些列即可检测是否有记录。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多