0

我正在尝试创建一个 SQLite 数据库,但遇到了一个似乎源自从未创建的表 CONTACTS 的问题(我收到错误消息“插入'无此类表时出错:CONTACTS'')。

从下面的代码中,任何人都可以看出什么是错误的以及如何纠正它?这个例子直接取自本指南,这就是为什么我很惊讶它不起作用: http ://www.techotopia.com/index.php/An_Example_SQLite_based_iOS_6_iPhone_Application

- (void)viewDidLoad 
{  
    [super viewDidLoad];
    NSString *docsDir;
    NSArray *dirPaths;

    // Get the documents directory

    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    docsDir = dirPaths[0];

    //Buid the path for database file
    _databasePath = [[NSString alloc]
                     initWithString:[docsDir stringByAppendingPathComponent:@"contacts.db"]];

    NSFileManager *filemgr = [NSFileManager defaultManager];

    if([filemgr fileExistsAtPath: _databasePath ] == NO)
    {
        const char *db_path = [_databasePath UTF8String];

        if(sqlite3_open(db_path, &_contactDB) == SQLITE_OK)
        {
            char *errMsg;

            const char *sql_stmt =
            "CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT)";

            if (sqlite3_exec(_contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
            {
                _text.text = @"Failed to create table";
            }
            sqlite3_close(_contactDB);
        } else { 
            _text.text = @"Failed to open/create database";
        }
    }

}

- (IBAction)saveName:(id)sender {


NSString *currentName = self.text.text;
NSString *nameSaved = [[NSString alloc] initWithFormat:currentName];


    sqlite3_stmt    *statement;
    const char *dbpath = [_databasePath UTF8String];

    if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
    {
        NSLog(@"pass");
        NSString *insertSQL = [NSString stringWithFormat:
                               @"INSERT INTO CONTACTS (name) VALUES (\"%@\")",
                               nameSaved];

        const char *insert_stmt = [insertSQL UTF8String];
        sqlite3_prepare_v2(_contactDB, insert_stmt,
                           -1, &statement, NULL);
        if (sqlite3_step(statement) == SQLITE_DONE)
        {
        NSLog(@"pass");
        } else {
        NSLog( @"Error while inserting '%s'", sqlite3_errmsg(_contactDB));
        }
        sqlite3_finalize(statement);
        sqlite3_close(_contactDB);

    }  
}
4

2 回答 2

0

使用objectAtIndex

sqlite3*    _contactDB;
NSString *docsDir;
NSArray *dirPaths;

// Get the documents directory

dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];

//Buid the path for database file
  NSString *  _databasePath = [[NSString alloc]
                     initWithString:[docsDir stringByAppendingPathComponent:@"contacts.db"]];

NSFileManager *filemgr = [NSFileManager defaultManager];

if([filemgr fileExistsAtPath: _databasePath ] == NO)
{
    const char *db_path = [_databasePath UTF8String];

    if(sqlite3_open(db_path, &_contactDB) == SQLITE_OK)
    {
        char *errMsg;

        const char *sql_stmt =
        "CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT)";

        if (sqlite3_exec(_contactDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
        {
            NSLog(@"Failed to create table") ;
        }
        sqlite3_close(_contactDB);
    } else { 
       NSLog( @"Failed to open/create database");
    }
}
于 2013-05-24T15:27:04.270 回答
0

该代码没有任何问题——它在 Mac OS X 和 iOS 模拟器上运行良好。当您尝试将数据插入表中时,错误是否会稍后出现?您是否在尝试将数据插入文件之前关闭文件?

在模拟器中运行它,单步执行代码,然后在模拟器的 Documents 目录中找到该文件。使用终端查看文件中的内容:

sqlite3 path-to-file .dump

您的机器上的确切路径会有所不同,但在我的 iOS 模拟器中,我得到:

sqlite3 "/Users/my-login-name/Library/Application Support/iPhone Simulator/6.1/Applications/DAD0BB47-2136-4367-8DAF-AA578D0C00A5/Documents/contacts.db" .dump
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT);
COMMIT;

您可以看到该表存在正确的列。

于 2013-05-24T15:48:06.220 回答