我几天来一直在玩C ++的sqlite3库,但这让我感到非常沮丧。
我想定义一个参数化的CREATE TABLE,然后将参数绑定到它。它看起来像这样:
const char[] CREATE_SQL =
"CRAETE TABLE t1 ("
" name VARCHAR(:NAME_LEN)"
" other VARCHAR(:OTHER_LEN)"
");";
我的想法是在另一个文件(此头文件的.cpp)中,我可以将这些参数绑定到:
int index = sqlite3_bind_parameter_index(stmt, ":NAME_LEN");
sqlite3_bind_int(stmt, index, _DB_FIELD_SIZE_NAME);
其中_DB_FIELD_SIZE_NAME也在别处定义。
我不想将sprintf()
与CREATE_SQL
包含%d
而不是:NAME_LEN
和:OTHER_LEN
一起使用,因为我可能会更改参数的顺序或添加新的,我想保持绑定明确。
现在,对于这个问题:我的prepare不会返回SQLITE_OK
,但会导致sqlite3_stmt
的空指针。这就是我所拥有的:
sqlite3_stmt *stmt;
const char *pStmt = 0;
if( SQLITE_OK != sqlite3_prepare_v2(*db, CREATE_SQL, -1, &stmt, &pStmt) )
// throws exception with the sqlite3_errmsg(*db) text
所以,我得到的错误是:
near ":NAME_LEN": syntax error
我做错了什么?我确信数据库连接打开正常。
答案 0 :(得分:0)
为了不回答您的问题,sqlite没有严格的文本列大小调整。它为了兼容性而接受VARCHAR类型,但它的行为没有变化。
你总会得到与此相当的东西:
const char *sql =
"CREATE TABLE t1 ("
" name TEXT"
" ,other TEXT"
");";
要回答你的问题,我不相信你可以这样做。 Sqlite的替换机制仅适用于通常被视为值参数的东西。
例如,您在INSERT
或UPDATE
语句中通常会看到的内容。
const char *sql = "INSERT INTO foo (a,b) VALUES (?1,?);";
我不记得你是否可以在CREATE
语句中完成它们,可能是默认参数?已经很久了。
我发现boost::format
不太可能打破并创建比我必须更改非值参数时尝试的任何其他解决方案更清晰的代码。
#include <boost/format.hpp>
// ...
int instance_id = 42;
const char *sql = "CREATE TABLE type_%1% (a,b);";
boost::str( boost::format(sql) % instance_id );
我绝对鼓励你避免做非值参数替换,除非绝对必须这样做。这是一个维护麻烦和容易出错。