如何使用 datetime('now', '-1 day') 使用准备好的语句检索 sqlite3 数据库中的行?
How do I retrieve rows in an sqlite3 database using prepared statements using datetime('now', '-1 day')?
给定一个 table 设计如下:
CREATE TABLE calls(timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, callerid TEXT, contactid INTEGER)
如果我想提取时间戳在 1 天内的所有行,我可以使用此 sql:
SELECT * FROM calls WHERE timestamp >= datetime('now', '-1 day');
在使用不安全便利函数的代码中,我可以这样写:
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 returns SQLITE_DONE 立即,即 returns 没有数据。
我应该如何设置对准备好的语句函数的调用才能使其正常工作。
使用 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);
给定一个 table 设计如下:
CREATE TABLE calls(timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, callerid TEXT, contactid INTEGER)
如果我想提取时间戳在 1 天内的所有行,我可以使用此 sql:
SELECT * FROM calls WHERE timestamp >= datetime('now', '-1 day');
在使用不安全便利函数的代码中,我可以这样写:
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 returns SQLITE_DONE 立即,即 returns 没有数据。
我应该如何设置对准备好的语句函数的调用才能使其正常工作。
使用 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);