sqlite3(C语言):没有这样的列

3

我希望将USB中的数据保存到sqlite3数据库中。

以下是来自USB的数据:

char T0[8], T1[8], T2[8], T3[8], T4[8];

我使用以下代码创建了一张表:

const char* Temprature_table = "Create table Temprature_1 (ID INTERGER PRIMARY KEY,Thermo_0 decimal(5,1),Thermo_1 decimal(5,1),Thermo_2 decimal(5,1),Thermo_3 decimal(5,1),Thermo_4 decimal(5,1),time DATETIME)";

然后我将数据插入到表中

result = sqlite3_exec (DB,"Insert  into Temprature VALUES(NULL, T0, T1, T2, T3, T4, time)",0,0,&errmsg);

或者

char array[256];
sprintf(array, "Insert into Temprature_1 VALUES(NULL, T0, T1, T2, T3, T4, time)");
result = sqlite3_exec (DB,array,0,0,&errmsg);

但是有一个问题:“无法插入数据:没有这样的列:T0”。 我不知道为什么。 谢谢。

欢迎来到Stack Overflow。请小心复制材料到你的问题中;你的CREATE TABLE语句试图创建一个类型为INTERGER的列(名称中带了一个多余的R),这是行不通的(或者很少能成功)。你的表名有轻微的拼写错误;正常的拼写是Temperature(但由于你保持一致,这不是一个关键问题)。 - Jonathan Leffler
3个回答

2

您的C代码和SQL代码运行在不同的域中,它们不共享变量。因此,您无法直接从SQL代码访问C变量。根据文档,这似乎是正确的解决方案:

sqlite3_stmt *ppStmt;
sqlite3_prepare_v2(DB, "Insert into Temprature_1 VALUES(NULL, ?, ?, ?, ?, ?, time)", 58, &ppStmt, NULL);

sqlite3_bind_text(ppStmt, 1, T0, 8, SQLITE_TRANSIENT);
sqlite3_bind_text(ppStmt, 2, T1, 8, SQLITE_TRANSIENT);
sqlite3_bind_text(ppStmt, 3, T2, 8, SQLITE_TRANSIENT);
sqlite3_bind_text(ppStmt, 4, T3, 8, SQLITE_TRANSIENT);
sqlite3_bind_text(ppStmt, 5, T4, 8, SQLITE_TRANSIENT);

sqlite3_step(ppStmt);
sqlite3_finalize(ppStmt);

1

在处理查询时,您应该使用预处理语句绑定值。一个常规的SQL语句通常具有以下形式:

INSERT INTO Temperature_1 (Thermo_0, Thermo_1) VALUES (23.2, 42.3)

一个预编译语句看起来像

INSERT INTO Temperature_1 (Thermo_0, Thermo_1) VALUES (?, ?)

这可以实现安全和性能的增强。因此,您的最终代码将如下所示

sqlite3_stmt *stmt;

sqlite3_prepare_v2(
  db,
  "INSERT INTO Temperature (Thermo_0, Thermo_1) VALUES (?, ?)",
  -1,
  &stmt,
  NULL
);

sqlite3_bind_text(stmt, 1, T0, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, T1, -1, SQLITE_TRANSIENT);

sqlite3_step(stmt);

请参考SQLite介绍中的C API。您的代码无法正常工作,因为您向查询引擎提交了以下字符串

INSERT INTO table (T0);

虽然INSERT语句的语法看起来像是

INSERT INTO <table> VALUES (<expression>[, <expression>[, ...]])

当数据库引擎评估您的查询时,它无法知道TO恰好是代码中某个变量的名称,因此会发出该错误。 SQL是一种独立的语言,与C上下文没有任何共享。

最后注意,正确的拼写似乎应该是TEMPERATURE,而不是TEMPRATURE(PR后面缺少一个E)


1

在 SQL 查询字符串中不要包含 C 变量的名称。

您可以直接包含一个文本值(例如通过从较小的部分编程组合字符串,例如使用 sprintf),或者使用参数占位符。后者更加强大,可以防止 SQL 注入攻击,并且通常更受欢迎。对于以 C 作为宿主语言的情况,这也将为您节省为粘贴的查询分配足够内存的麻烦。

您可以通过 创建 预处理语句绑定参数 到它来使用 占位符。当您 执行 该语句时,绑定的参数将在占位符指示的位置使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接