2

Xcode sqlite db のデータを更新したいと思います。データベースは正常に接続されていますが、SQL ステートメントに何か問題があるようです。「連絡先の追加に失敗しました」というメッセージが返され続けます。

- (void) saveData:(id)sender
{

    NSLog(@"The code runs through here!");
    sqlite3_stmt    *statement;

    NSString *documents = [self applicationDocumentsDirectory];
    NSString *dbPath = [documents stringByAppendingPathComponent:@"monitorDB.sqlite"];
    const char *dbpath = [dbPath cStringUsingEncoding:NSASCIIStringEncoding];

    if (sqlite3_open(dbpath, & contactDB) == SQLITE_OK)
    {

        NSString *insertSQL = [NSString stringWithFormat:
                               @"UPDATE profile SET username = \"%@\" WHERE id = 1" ,
                               self.username.text];

        const char *insert_stmt = [insertSQL UTF8String];
        sqlite3_prepare_v2(contactDB, insert_stmt,
                           -1, &statement, NULL);
        if (sqlite3_step(statement) == SQLITE_DONE)
        {
            self.settingStatus.text = @"Contact added";
        } else {
            self.settingStatus.text = @"Failed to add contact";
        }
        sqlite3_finalize(statement);
        sqlite3_close(contactDB);
    }   else {
        self.settingStatus.text = @"DB Not Connect";
    }



}
4

5 に答える 5

7

このようにしてみてください..

viewdidload では、テーブルが存在するかどうかを確認する必要があります。そうでない場合は、db を作成する必要があります。

NSString *docsdir;
NSArray *dirpaths;

dirpaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsdir=[dirpaths objectAtIndex:0];
dabasePath=[NSString stringWithFormat:[docsdir stringByAppendingPathComponent:@"contact.db"]];

NSFileManager *filemgr= [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath:dabasePath]==NO ) {
    const char *dbpath=[dabasePath UTF8String];
    if (sqlite3_open(dbpath, &contactDB)== SQLITE_OK) {
        char *error;
        const char *sql_stmt="CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, ADDRESS TEXT, NAME TEXT, PHONE TEXT, IMAGE BLOB)";
        if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &error)!= SQLITE_OK) {
            status.text=@"failed to create";
        }
        sqlite3_close(contactDB);
    }
}

データを保存するには、次のコードを使用してみてください。

-(IBAction)saveData:(id)sender{

    sqlite3_stmt *statement;
    const char *dbpath = [dabasePath UTF8String];
    NSData *imagedata=UIImagePNGRepresentation(imageview.image);
    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK) {
        NSString *insertSql =[NSString stringWithFormat:@"INSERT INTO CONTACTS (name, address, phone, image) VALUES (\"%@\", \"%@\", \"%@\", ?) ", name.text, address.text, phone.text ];
        // NSString *nam=name.text;
        const char *insert_stmt = [insertSql UTF8String];
        sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
        sqlite3_bind_blob(statement, 1, [imagedata bytes], [imagedata length], NULL);

        if (sqlite3_step(statement) == SQLITE_DONE) {
          status.text=@"contact added";
          [self clearClick:nil];
        }else{
          status.text=@"failed to added";
        }
        sqlite3_finalize(statement);
        sqlite3_close(contactDB);
    }
}

データを更新するには、次のコードを使用してみてください。

-(IBAction)updateClick:(id)sender{

sqlite3_stmt *updateStmt;
 const char *dbpath = [dabasePath UTF8String];
if(sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
{
    const char *sql = "update contacts Set address = ?, phone = ?, image = ? Where name=?";
    if(sqlite3_prepare_v2(contactDB, sql, -1, &updateStmt, NULL)==SQLITE_OK){
        sqlite3_bind_text(updateStmt, 4, [name.text UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(updateStmt, 1, [address.text UTF8String], -1, SQLITE_TRANSIENT);
        sqlite3_bind_text(updateStmt, 2, [phone.text UTF8String], -1, SQLITE_TRANSIENT);
        NSData *imagedata=UIImagePNGRepresentation(imageview.image);
        sqlite3_bind_blob(updateStmt, 3, [imagedata bytes], [imagedata length], NULL);
    }
}
char* errmsg;
sqlite3_exec(contactDB, "COMMIT", NULL, NULL, &errmsg);

if(SQLITE_DONE != sqlite3_step(updateStmt)){
    NSLog(@"Error while updating. %s", sqlite3_errmsg(contactDB));
}
else{
    [self clearClick:nil];
}
sqlite3_finalize(updateStmt);
sqlite3_close(contactDB);
}
于 2013-09-10T08:48:25.290 に答える
0

多くの可能性があり、以下のすべてを確認してください。

1) ステートメントを nil で初期化する

sqlite3_stmt    *statement = nil;

2)以下を試してください

if (sqlite3_prepare_v2(contactDB, insert_stmt,-1, &statement, NULL) == SQLITE_OK)
{
 while (sqlite3_step(statement) == SQLITE_ROW)
 {
   //Updated
 }
}
else
{
    NSLog(@"error is %s",sqlite3_errmsg(database));
}
于 2013-09-10T08:56:47.417 に答える
-1

dbPath がアプリ バンドルに含まれていませんか? バンドル内の db を更新できません。

sqlite3_prepare_v2() and sqlite3_step() will return an int.

必要なものは sqlite3.h で見つけることができます。

Like #define SQLITE_BUSY         5   /* The database file is locked */ ...

そして、なぜ FMDB を使用しないのですか? Github で簡単に見つけることができます。(リンクhttps://github.com/ccgus/fmdb )

于 2013-09-10T08:17:19.320 に答える