简体   繁体   English

C和Sqlite3-变量数据库和表命名-SQL语法错误

[英]C & Sqlite3 - Variable database & table naming - SQL Syntax error

I'm trying to write some code that initializes an sql database and table with the name of the database & table set through preprocessor commands and if not set, defaulting to the values given below. 我正在尝试编写一些代码,以通过预处理程序命令设置的数据库和表的名称初始化sql数据库和表,如果未设置,则默认为以下给出的值。

I'm using a macro to stringify whatever name is given. 我正在使用宏来对给出的任何名称进行字符串化。 The sqlite3_open correctly opens / creates the database with the given name or the default sqlite3_open可以正确打开/创建具有给定名称或默认名称的数据库

sqlite3_open(TO_STRING(DB_NAME), &db);

For the creation of the table I'm relying on sprintf. 对于表的创建,我依靠sprintf。

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

When inspecting my code in debugging, pointer sql seems to be having the correct value of "CREATE TABLE SensorData;". 在调试中检查我的代码时,指针sql似乎具有正确的值“ CREATE TABLE SensorData;”。 However when I try to execute my code I get the error "SQL error: near ";": syntax error" . 但是,当我尝试执行代码时,出现错误“ SQL错误:在”;附近“:语法错误” Upon inspection it is clear that the error code 110 is returned by the function, I can't seem to find any information on this code however. 经过检查,很明显该函数返回了错误代码110,但是我似乎找不到关于此代码的任何信息。

I can't seem to figure out what the exact problem is in this case, as the string resulting in the array str seems to be exactly the same as when I create the table in a static way. 在这种情况下,我似乎无法弄清楚究竟是什么问题,因为导致数组str的字符串似乎与以静态方式创建表时的字符串完全相同。

This is all my code relevant to the problem. 这是我所有与问题有关的代码。

#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;

}

To turn @Simone Cifani 's comment into a valid answer. 将@Simone Cifani的评论转换为有效答案。 The problem was that my CREATE TABLE query was invalid as I did not add any fields to the table. 问题是我的CREATE TABLE查询无效,因为我没有向表中添加任何字段。 Following solution solved the problem. 以下解决方案解决了问题。

Note that I also swapped the sprintf function for the asprintf function, which I highly suggest you read up on if you are planning to do anything similar to this. 请注意,我还将sprintf函数替换为asprintf函数,如果您打算执行与此类似的操作,我强烈建议您继续阅读。 This thread explains the working of the asprintf function and the difference with the sprintf function very clearly. 该线程非常清楚地解释了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;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM