C& Sqlite3 - 可变数据库&表命名 - SQL语法错误

时间:2017-05-10 11:00:39

标签: c sqlite c-preprocessor

我正在尝试编写一些代码来初始化一个sql数据库和一个带有数据库名称的表。 table set通过预处理程序命令设置,如果没有设置,则默认为下面给出的值。

我正在使用宏来字符串化所给出的任何名称。 sqlite3_open正确打开/创建具有给定名称或默认

的数据库
sqlite3_open(TO_STRING(DB_NAME), &db);

为了创建表格,我依赖于sprintf。

sprintf(str,"CREATE TABLE %s;", TO_STRING(TABLE_NAME));
sql = str;

在调试中检查我的代码时,指针sql似乎具有正确的值“CREATE TABLE SensorData;”。但是当我尝试执行我的代码时,我收到错误 “SQL错误:接近”;“:语法错误” 。在检查时,很明显函数返回了错误代码110,但我似乎无法找到有关此代码的任何信息。

我似乎无法弄清楚在这种情况下确切的问题是什么,因为导致数组str的字符串似乎与我以静态方式创建表时完全相同。

这是我所有与此问题相关的代码。

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

#define REAL_TO_STRING(s) #s
#define TO_STRING(s) REAL_TO_STRING(s)   

#ifndef DB_NAME
  #define DB_NAME Sensor.db
#endif

#ifndef TABLE_NAME
  #define TABLE_NAME SensorData
#endif

#define DBCONN sqlite3 

int main()
{

    char *err_msg = 0;
    DBCONN * db;
    int ok = sqlite3_open(TO_STRING(DB_NAME), &db);


    if(ok != SQLITE_OK)
    {
        fprintf(stderr,"Cannot open database: %s\n",sqlite3_errmsg(db));
        sqlite3_close(db);
        return 0;
    }

    char * sql;
    char str[100];
    //clear array
    memset(&str[0],0,100);  

    sprintf(str,"CREATE TABLE %s;", TO_STRING(TABLE_NAME));
    sql = str;

    ok = sqlite3_exec(db, sql, 0, 0, &err_msg);

    if (ok != SQLITE_OK ){

      fprintf(stderr, "SQL error: %s\n", err_msg);

      sqlite3_free(err_msg);        
      sqlite3_close(db);

      return 0;
  }

    sqlite3_close(db);

    return 0;

}

1 个答案:

答案 0 :(得分:0)

将@Simone Cifani的评论转变为有效答案。问题是我的CREATE TABLE查询无效,因为我没有向表中添加任何字段。以下解决方案解决了这个问题。

请注意,我还将sprintf函数替换为asprintf函数,如果您打算执行类似的操作,我强烈建议您阅读。 This thread非常清楚地解释了asprintf函数的工作以及与sprintf函数的区别。

#define _GNU_SOURCE 

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

#define REAL_TO_STRING(s) #s
#define TO_STRING(s) REAL_TO_STRING(s)   

#ifndef DB_NAME
  #define DB_NAME Sensor.db
#endif

#ifndef TABLE_NAME
  #define TABLE_NAME SensorData
#endif

#define DBCONN sqlite3 

int main()
{

    char *err_msg = 0;
    DBCONN * db;
    int rc = sqlite3_open(TO_STRING(DB_NAME), &db);

    if(rc != SQLITE_OK)
    {
        fprintf(stderr,"Cannot open database: %s\n",sqlite3_errmsg(db));
        sqlite3_close(db);
        return 0;
    }

    char * sql;
    int size = 0;

    size  = asprintf(&sql,"CREATE TABLE %s (id INT, value REAL, ts INT);", TO_STRING(TABLE_NAME));

    if(size == -1)
        printf("asprintf failed in main\n");

    rc = sqlite3_exec(db, sql, 0, 0, &err_msg);

    if (rc != SQLITE_OK ){

      fprintf(stderr, "SQL error: %s\n", err_msg);
      sqlite3_free(err_msg);        
      sqlite3_close(db);
      free(sql);
      return 0;
  }

    free(sql);
    sqlite3_close(db);
    return 0;

}