我对sqlite很新,特别是在C设置中。我试图在我的表格中插入一条记录。
这是我的代码:
int InsertIntoFileActionTable(FileActionData* fad)
{
sqlite3_stmt * stmt;
char *ErrMsg;
const char *pzTail;
int result = 0;
string sql;
sql = "INSERT INTO FileActionData (RootName, RootDirectory, RelativePath, ParentPath, FileName, Stem, Extension, UserName, SignalFlag, ProcessID, ProtectionOn, BSSMember, ProcessTime) ";
sql += "VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
result = sqlite3_prepare(pDb, &sql[0], 1000, &stmt, &pzTail);//This reseult is x00001
result = sqlite3_bind_text16(stmt, 1, (void*)(&fad->RootName[0]), fad->RootName.length(), SQLITE_STATIC);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_text16(stmt, 2, (void*)(&fad->RootDirectory[0]), fad->RelativePath.length(), SQLITE_STATIC);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_text16(stmt, 3, (void*)(&fad->RelativePath[0]), fad->RelativePath.length(), SQLITE_STATIC);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_text16(stmt, 4, (void*)(&fad->ParentPath[0]), fad->ParentPath.length(), SQLITE_STATIC);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_text16(stmt, 5, (void*)(&fad->FileName[0]), fad->FileName.length(), SQLITE_STATIC);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_text16(stmt, 6, (void*)(&fad->Stem[0]), fad->Stem.length(), SQLITE_STATIC);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_text16(stmt, 7, (void*)(&fad->Extension[0]), fad->Extension.length(), SQLITE_STATIC);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_text16(stmt, 8, (void*)(&fad->UserName[0]), fad->UserName.length(), SQLITE_STATIC);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_int(stmt, 9, fad->SignalFlag);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_int(stmt, 10, fad->ProcessID);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_int(stmt, 11, fad->ProtectionOn);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_int(stmt, 12, fad->BSSMember);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_bind_int(stmt, 13, fad->ProcessTime);//This reseult is x00015 SQLITE_MISUSE
result = sqlite3_step(stmt);//This reseult is x00015 SQLITE_MISUSE
if (result == SQLITE_MISUSE)
{
printf("MISUSE error");
}
return result;
}
这是我的FileActionData定义:
class FileActionData
{
public:
std::wstring RootName;
std::wstring RootDirectory;
std::wstring RelativePath;
std::wstring ParentPath;
std::wstring FileName;
std::wstring Stem;
std::wstring Extension;
unsigned long SignalFlag;
unsigned long ProcessID;
BOOL ProtectionOn;
BOOL BSSMember;
std::wstring UserName;
time_t ProcessTime;
};
我得到的错误是Prepare上的1(Generic)和其他来电时的x15(21)(Misuse)。
添加了其他信息: 我也尝试过:
result = sqlite3_prepare16_v3(pDb, &sql[0], 1000, 0, &stmt, (const
void**)&pzTail);//This result is x00001
stmt为null,这就是我的其余调用返回Misuse的原因。
pDb在其他地方开放。
我做错了什么? TIA
答案 0 :(得分:0)
查看sqlite的文档:
https://www.sqlite.org/capi3ref.html#sqlite3_bind_blob
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
第三个参数是绑定到参数的值。如果
sqlite3_bind_text()
或sqlite3_bind_text16()
或sqlite3_bind_blob()
的第三个参数是NULL
指针,则忽略第四个参数,最终结果与sqlite3_bind_null()
相同。在具有第四个参数的那些例程中,其值是参数中的字节数。要清楚:值是值中的字节数,而不是字符数。如果
sqlite3_bind_text()
或sqlite3_bind_text16()
的第四个参数是负数,那么字符串的长度是第一个零终止符之前的字节数。如果sqlite3_bind_blob()
的第四个参数为负,则行为未定义。如果向sqlite3_bind_text()
或sqlite3_bind_text16()
或sqlite3_bind_text64()
提供了非负的第四个参数,则该参数必须是假定字符串NUL终止时NUL终结符将发生的字节偏移量。如果在字节偏移小于第四个参数的值时出现任何NUL字符,则结果字符串值将包含嵌入的NUL。涉及具有嵌入式NUL的字符串的表达式的结果是未定义的。
第三个参数应该是一个字符串,第四个参数应该是字节大小,而不是 字符串长度。
应该是 1
result = sqlite3_bind_text16(stmt, 1, (void*)(fad->RootName.c_str()),
fad->RootName.size() * sizeof(wchar_t), SQLITE_STATIC);
或者Mark Benningfield建议:
result = sqlite3_bind_text16(stmt, 1, (void*)(fad->RootName.c_str()),
-1, SQLITE_STATIC);
1 我没有太多地使用C ++,这就是为什么我不得不查看如何获得
std::wstring
的大小。我发现了这个:How can I get the byte size of std::wstring?
答案 1 :(得分:0)
我不得不做一些研究以确认我的唠叨怀疑。 std::string
的内部表示不保证在内存中是连续的,甚至不能终止(直到C ++ 11,我不确定Visual Studio是否完全实现),所以发送SQLite第一个角色的地址不起作用。
为SQL文本定义char*
,然后传递,或将调用结果传递给.c_str()
成员函数。这同样适用于后续参数绑定调用:您也不能传递std::wstring
的第一个字符的地址。
如果你有一个有效的UTF-8 sql语句,传递-1让SQLite将文本解析为空终止符,并且数据库句柄实际上是打开的,它应该可以工作。