【发布时间】:2013-03-07 22:33:38
【问题描述】:
我正在编写一个直接访问SQLite 的iOS 应用程序。我在 Android 上做过很多次这样的事情,所以我很难找出我的错误所在 - 但是我的插入返回 SQLITE_MISUSE 错误(代码 21),并显示消息“内存不足”。以下是我为引导我进入此插页所采取的步骤。
首先,表创建:
NSString *sql = @"CREATE TABLE IF NOT EXISTS UsersTable (lastName TEXT,id TEXT PRIMARY KEY NOT NULL,picture BLOB,firstName TEXT,age TEXT,email TEXT,sex TEXT,height TEXT,weight TEXT)";
//create the database if it does not yet exist
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: path ] == NO)
{
const char *dbpath = [path UTF8String];
//This was if (sqlite3_open(dbpath, &store) == SQLITE_OK) , but it has not made a difference.
if (sqlite3_open_v2(dbpath, &store, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) == SQLITE_OK)
{
char *errMsg = NULL;
const char *sql_stmt = [sql UTF8String];
if (sqlite3_exec(store, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
NSLog(@"Failed to create table: %s", errMsg);
}
if (errMsg)
sqlite3_free(errMsg);
}
else
{
NSLog(@"Failed to open/create database");
}
}
接下来,插入(当前使用电子邮件地址作为用户 ID):
INSERT INTO UsersTable (id,lastName,firstName,email) VALUES ("jsmith@foobar.com","Smith","John","jsmith@foobar.com")
我对所有数据库交互都使用一个选择器,所以上面的文字在这里传递:
-(int)execSQL:(NSString *)statement
{
NSLog(@"%@",statement);
const char *insert_stmt = [statement UTF8String];
sqlite3_stmt *stmnt;
sqlite3_prepare_v2(store, insert_stmt, -1, &stmnt, NULL);
int result = sqlite3_step(stmnt);
sqlite3_finalize(stmnt);
if (result != SQLITE_OK)
{
NSLog(@"Error: %s", sqlite3_errmsg(store));//This prints "Error: out of memory"
}
return result;
}
我做错了什么?
【问题讨论】:
-
获取完整错误。
NSLog(@"Error: %s", sqlite3_errmsg(store));. -
sqlite 要求文本值使用单引号,而不是双引号。
-
最后一件事——以防万一——不要使用字符串格式来创建 SQL 语句。准备语句,然后使用
sqlite3_bind_xxx将值绑定到查询中。INSERT INTO table (c1, c2, c2) VALUES (?, ?, ?)。对sqlite3_bind_xxx的调用将用正确的值替换?。这可确保正确引用值并正确转义特殊字符。 -
“内存不足”错误几乎总是意味着您的数据库指针(您的
sqlite3 *变量)没有通过调用sqlite3_open_v2正确设置。 -
@rmaddy 我添加了用于打开数据库的代码,并从使用
sqlite3_open更改为sqlite3_open_v2,但仍然遇到相同的错误。还有其他指针吗? (我目前正在处理您的其他建议)
标签: ios objective-c sqlite