这是我的代码:
在我的ViewDidLoad中创建数据库:
NSString *docsDir;
NSArray *dirPaths;
dirPaths=NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"contacts.db"]];
NSFileManager *filemgr=[NSFileManager defaultManager];
if ([filemgr fileExistsAtPath:databasePath]==NO)
{
NSLog(@"Creating DB");
const char *dbpath=[databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB)==SQLITE_OK)
{
char *error_msg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, URL TEXT, EMAIL TEXT, CODE TEXT, FULL TEXT)";
if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &error_msg) != SQLITE_OK)
{
NSLog(@"Failed to create table");
}
sqlite3_close(contactDB);
} else {
NSLog(@"Failed to open/create database");
}
} else {
NSLog(@"DB exists");
}
我可以看到输出消息"Creating DB"
然后我必须在那里添加我的数据:
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO CONTACTS (url, email, code, full) VALUES (\"%@\", \"%@\", \"%@\", \"%@\")", url_2, mail, keycode,full_2 ];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(@"Contact added");
} else {
NSLog(@"Failed to add contact");
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
} else {
NSLog(@"PROBLEM - CONTACT NOT ADDED");
}
我看到了"PROBLEM - CONTACT NOT ADDED"
消息。
任何帮助?
答案 0 :(得分:3)
问题是您要在NSDocumentationDirectory
而不是NSDocumentDirectory
中打开数据库。
几个不相关的观察结果:
如果sqlite3_open()
失败,您应该查看数字返回代码,它将帮助您诊断问题的根源。您可以在sqlite3.h
标题文件中查找值。
对您的代码示例无关的观察:您应该检查sqlite3_prepare_v2()
返回代码,因为通常会在那里识别SQL错误,而不是sqlite3_step()
。如果它返回SQLITE_OK
以外的内容,则立即致电sqlite3_errmsg()
以确定其失败原因。
您不应使用stringWithFormat
为INSERT
SQL语句添加值。相反,使用?
占位符,然后使用sqlite3_bind_XXX()
函数将值绑定到这些SQL值。实际上,如果任何插入的值包含引号,则SQL将失败(并且容易受到SQL注入攻击)。
答案 1 :(得分:1)
你犯了一个小错误,如@Rob所示......
而不是
dirPaths=NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
你应该使用
dirPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
以下是更正后的代码,
NSString *docsDir;
NSArray *dirPaths;
dirPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"contacts.db"]];
NSFileManager *filemgr=[NSFileManager defaultManager];
if ([filemgr fileExistsAtPath:databasePath]==NO)
{
NSLog(@"Creating Database...");
const char *dbpath=[databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB)==SQLITE_OK)
{
char *error_msg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, URL TEXT, EMAIL TEXT, CODE TEXT, FULL TEXT)";
if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &error_msg) != SQLITE_OK)
{
NSLog(@"Failed to create table");
}
sqlite3_close(contactDB);
}
else
{
NSLog(@"Failed to open/create database");
}
}
else
{
NSLog(@"DB exists");
}
您可以插入这样的数据,
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO CONTACTS (url, email, code, full) VALUES (\"%@\", \"%@\", \"%@\", \"%@\")", url_2, mail, keycode,full_2 ];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(@"Contact added");
}
else
{
NSLog(@"Failed to add contact");
}
sqlite3_finalize(statement);
sqlite3_close(contactDB);
}
else
{
NSLog(@"PROBLEM - CONTACT NOT ADDED");
}
谢谢...... !!!