2013-01-04 106 views
2

这里是我的代码:不能将数据添加到本地数据库SQLite的IOS

为了创建数据库,在我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"消息。

任何帮助?

回答

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"); 
} 

谢谢...!

3

问题是你打开你的数据库在NSDocumentationDirectory,而不是NSDocumentDirectory

几个不相关的意见:

  1. 如果sqlite3_open()失败,你应该看看数字返回码,这将帮助您诊断问题的根源。您可以在sqlite3.h头文件中查找值。

  2. 与您的代码示例无关:您应该检查您的sqlite3_prepare_v2()返回码,因为SQL错误通常在那里标识,而不是sqlite3_step()。如果返回SQLITE_OK以外的内容,请立即致电sqlite3_errmsg()以确定其失败的原因。

  3. 您不应该使用stringWithFormatINSERT SQL语句添加值。请改用?占位符,然后使用sqlite3_bind_XXX()函数将值绑定到这些SQL值。实际上,如果任何插入的值包含引号,则SQL将失败(并且容易受到SQL注入攻击)。