C语言 如何使用datetime('now','-1 day')的预处理语句在sqlite3数据库中检索行?

efzxgjgh  于 7个月前  发布在  SQLite
关注(0)|答案(2)|浏览(92)

给定一个这样设计的表:

CREATE TABLE calls(timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, callerid TEXT, contactid INTEGER)

字符串
如果我想提取时间戳在1天内的所有行,我可以使用这个sql:

SELECT * FROM calls WHERE timestamp >= datetime('now', '-1 day');


在使用unsafe方便函数的代码中,我可以这样写:

sqlite3 *db;
char *err_msg = 0;
int rc = sqlite3_open("mydb.db", &db);
const char* sql = "SELECT * FROM calls WHERE timestamp >= datetime('now', '-1 day');";
rc = sqlite3_exec(db, sql, callback, 0, &err_msg);


当然,我必须设置回调函数来处理记录的检索。
但是,如果我想用一个准备好的语句来执行相同的SELECT语句,我该怎么做呢?
我试着这样做:

sqlite3 *db;
char *err_msg = 0;
int rc = sqlite3_open("mydb.db", &db);

sqlite3_stmt *stmt = NULL;
const char* sql = "SELECT rowid,* FROM calls WHERE timestamp >= :timestamp;";
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);

int idx = sqlite3_bind_parameter_index(stmt, ":timestamp");
rc = sqlite3_bind_text(stmt, idx, "datetime('now', '-1 day')", -1, SQLITE_STATIC); break;

// but this while loop exits immediately - ie no data returned
while ((rc = sqlite3_step(stmt)) != SQLITE_DONE) {
  // code here to extract field data
}

rc = sqlite3_finalize(stmt);


但是sqlite3_step立即返回SQLITE_DONE,即它不返回数据。
我应该如何设置对准备好的语句函数的调用来使其工作。

woobm2wo

woobm2wo1#

使用SQLite的连接运算符||连接命名参数:days,它将是sql语句中类似"-1"的字符串:

const char* sql = "SELECT rowid, * FROM calls WHERE timestamp >= datetime('now', :days || ' day');";
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
int idx = sqlite3_bind_parameter_index(stmt, ":days");
rc = sqlite3_bind_text(stmt, idx, "-1", -1, SQLITE_STATIC);

字符串
或者,如果你想传递一个像"-1 day"这样的字符串,并带有一个命名参数:period

const char* sql = "SELECT rowid, * FROM calls WHERE timestamp >= datetime('now', :period);";
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
int idx = sqlite3_bind_parameter_index(stmt, ":period");
rc = sqlite3_bind_text(stmt, idx, "-1 day", -1, SQLITE_STATIC);

qlckcl4x

qlckcl4x2#

也许,您正在检索SQLITE_ROW,这是指示新记录准备好读取的返回代码,实际上与SQLITE_DONE不同?
根据sqlite3_step的文档和代码列表:

  • SQLITE_ROW:sqlite3_step()返回的SQLITE_ROW结果代码表明另一行输出可用。
  • SQLITE_DONE:SQLITE_DONE结果代码指示操作已完成。SQLITE_DONE结果代码最常被视为sqlite3_step()的返回值,指示SQL语句已运行完成。

关于sqlite3_step
如果正在执行的SQL语句返回任何数据,则每次有新的数据行准备好由调用者处理时都会返回SQLITE_ROW。可以使用列访问函数访问值。再次调用sqlite3_step()以检索下一行数据。

相关问题