如何使用 datetime('now', '-1 day') 使用准备好的语句检索 sqlite3 数据库中的行?

问题描述 投票:0回答:2

给定一个这样设计的桌子:

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立即返回SQLITE_DONE,即不返回任何数据。

我应该如何设置对准备好的语句函数的调用才能使其正常工作。

c sqlite prepared-statement
2个回答
1
投票

使用 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);

0
投票

也许,您正在检索

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() 以检索下一行数据。

© www.soinside.com 2019 - 2024. All rights reserved.