2

sqlite iPhoneのテーブルにデータを挿入する方法は?

私はフォローしようとしていますが、失敗します:

 NSString *query=[NSString stringWithFormat:@"insert into %@ (name) values ('%@')", table name,myName ];


 sqlite3 *database;

sqlite3_stmt *createStmt = nil;

if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
    if (createStmt == nil) {

        if (sqlite3_prepare_v2(database, [query UTF8String], -1, &createStmt, NULL) != SQLITE_OK) {
            return NO;
        }
        sqlite3_exec(database, [query UTF8String], NULL, NULL, NULL);
        return YES;
    }

    return YES;
}else {
    return NO;
}

次の方法でテーブルを作成しました。

create table if not exists myDets (dets_id integer primary key asc, name text);

また、FirefoxSQLiteプラグインを使用してデータベースをチェックしています。Firefox経由でデータベースにレコードを挿入しようとすると、次のエラーが発生します。

Failed to insert values
Exception Name: NS_ERROR_STORAGE_IOERR
Exception Message: Component returned failure code: 0x80630002 (NS_ERROR_STORAGE_IOERR)        [mozIStorageStatement.execute]

ひどく立ち往生:(

また、これをiPhoneシミュレーターで実行していますが、重要ですか?

助けてください

前もって感謝します。

4

2 に答える 2

3
- (NSString *) getDBPath {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
    NSString *documentsDir = [paths objectAtIndex:0];
    return [documentsDir stringByAppendingPathComponent:@"iHadDB.sqlite"];
}

- (void) insertValueToDatabase {

    NSString *dbPath =[self getDBPath];

    NSString *select_Meal = dummy_select_Meal;
    NSString *dateTime = dummy_date_Time;
    NSString *location = dummy_location;
    NSString *mealItem = dummy_mealItem;

    if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {

        const char *sqlDB = "Insert into iHad(Mealtype,DateAndTime,Location,Mealitem) VALUES (?,?,?,?)";

        if(sqlite3_prepare_v2(database, sqlDB, -1, &addStmt, NULL) != SQLITE_OK)
            NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));

        sqlite3_bind_text(addStmt, 1, [select_Meal UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(addStmt, 2, [dateTime UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(addStmt, 3, [location UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(addStmt, 4, [mealItem UTF8String], -1, SQLITE_TRANSIENT);

        if(SQLITE_DONE != sqlite3_step(addStmt))
            NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database));
        //else
            //SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
            //coffeeID = sqlite3_last_insert_rowid(database);

        //Reset the add statement.
        sqlite3_reset(addStmt);

    }
    else
        sqlite3_close(database); 

}
于 2012-05-03T04:33:26.697 に答える
3
  • パラメーターを使用し、更新ステートメントを文字列形式にしないでください
  • 多くのトレースを追加し、リターン コードを確認し、エラー コードを確認します (iPhone で発生しているエラーが不明な場合)。
  • sqlite3_errmsg を使用してエラー メッセージを取得する
  • dbPath を作成してログアウトします。エミュレーターのターミナルからデータベースを開くことができることを確認してください。sqlite はメモリ内にデータベースを受動的に作成するため、パスがオフでデータベースが存在しない場合、混乱を招く可能性があることに注意してください。
  • 更新ステートメントを印刷し、ログに記録したパスのターミナルで sqlite cmdline アプリから試してください。
  • データベースをメイン バンドル リソースに配置する場合、それはテンプレートであり、開いて書き込むためにはコピーする必要があります。

私のサンプルからの更新関数は次のとおりです。

- (void)updateContact: (Contact*)contact error:(NSError**)error
{
    if (![self ensureDatabaseOpen:error])
    {
        return;
    }

    NSLog(@">> ContactManager::updateContact");

    // prep statement
    sqlite3_stmt    *statement;
    NSString *querySQL = @"update contacts set name=?,address=?,phone=? where id=?";
    NSLog(@"query: %@", querySQL);
    const char *query_stmt = [querySQL UTF8String];

    // preparing a query compiles the query so it can be re-used.
    sqlite3_prepare_v2(_contactDb, query_stmt, -1, &statement, NULL);     
    sqlite3_bind_text(statement, 1, [[contact name] UTF8String], -1, SQLITE_STATIC);
    sqlite3_bind_text(statement, 2, [[contact address] UTF8String], -1, SQLITE_STATIC);
    sqlite3_bind_text(statement, 3, [[contact phone] UTF8String], -1, SQLITE_STATIC);
    sqlite3_bind_int64(statement, 4, [[contact id] longLongValue]);

    NSLog(@"bind name: %@", [contact name]);
    NSLog(@"bind address: %@", [contact address]);
    NSLog(@"bind phone: %@", [contact phone]);
    NSLog(@"bind int64: %qi", [[contact id] longLongValue]);

    // process result
    if (sqlite3_step(statement) != SQLITE_DONE)
    {
        NSLog(@"error: %s", sqlite3_errmsg(_contactDb));
    }

    sqlite3_finalize(statement);
}

サンプルでは、​​データベースをリソースからパスにコピーして開きます。これを行うために使用する確実に開かれた関数は次のとおりです。

- (BOOL)ensureDatabaseOpen: (NSError **)error
{
    // already created db connection
    if (_contactDb != nil)
    {
        return YES;
    }

    NSLog(@">> ContactManager::ensureDatabaseOpen");    
    if (![self ensureDatabasePrepared:error])
    {
        return NO;
    }

    const char *dbpath = [_dbPath UTF8String]; 
    if (sqlite3_open(dbpath, &_contactDb) != SQLITE_OK &&
        error != nil)
    {
        *error = [[[NSError alloc] initWithDomain:@"ContactsManager" code:1000 userInfo:nil] autorelease];
        return NO;
    }

    NSLog(@"opened");

    return YES;
}

- (BOOL)ensureDatabasePrepared: (NSError **)error
{
    // already prepared
    if ((_dbPath != nil) &&
        ([[NSFileManager defaultManager] fileExistsAtPath:_dbPath]))
    {
        return YES;
    }

    // db in main bundle - cant edit.  copy to library if !exist
    NSString *dbTemplatePath = [[NSBundle mainBundle] pathForResource:@"contacts" ofType:@"db"];
    NSLog(@"%@", dbTemplatePath);

    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
    _dbPath = [libraryPath stringByAppendingPathComponent:@"contacts.db"];

    NSLog(@"dbPath: %@", _dbPath);

    // copy db from template to library
    if (![[NSFileManager defaultManager] fileExistsAtPath:_dbPath])
    {
        NSLog(@"db not exists");
        NSError *error = nil;
        if (![[NSFileManager defaultManager] copyItemAtPath:dbTemplatePath toPath:_dbPath error:&error])
        {
            return NO;
        }

        NSLog(@"copied");
    }    

    return YES;    
}
于 2012-05-03T02:20:53.660 に答える