【问题标题】:SQLite behaviour on INSERT on iPhoneiPhone 上 INSERT 上的 SQLite 行为
【发布时间】:2010-11-28 04:37:56
【问题描述】:

作为我的 iPhone 应用程序的一部分,我目前正在执行以下操作

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"cities.sqlite"];

sqlite3 *database;

if(sqlite3_open([filePath UTF8String], &database) == SQLITE_OK) {
   const char *sqlStatement = "insert into table (name, description, image) VALUES (?, ?, ?)";
   sqlite3_stmt *compiledStatement;
   if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)    {
      sqlite3_bind_text( compiledStatement, 1, [name UTF8String], -1, SQLITE_TRANSIENT);
      sqlite3_bind_text( compiledStatement, 2, [description UTF8String], -1, SQLITE_TRANSIENT);
      NSData *dataForImage = UIImagePNGRepresentation(image);
      sqlite3_bind_blob( compiledStatement, 3, [dataForImage bytes], [dataForImage length], SQLITE_TRANSIENT);

   }
   if(sqlite3_step(compiledStatement) != SQLITE_DONE ) {
      NSLog( @"Error: %s", sqlite3_errmsg(database) );
   } else {
      NSLog( @"Insert into row id = %d", sqlite3_last_insert_rowid(database));
   }
   sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);

让我感到困惑的是,如果我把这个部分拿出来,

   if(sqlite3_step(compiledStatement) != SQLITE_DONE ) {
      NSLog( @"Error: %s", sqlite3_errmsg(database) );
   } else {
      NSLog( @"Insert into row id = %d", sqlite3_last_insert_rowid(database));
   }

INSERT 未保存到数据库并丢失。我假设我在这里遗漏了一些明显的东西?

【问题讨论】:

  • 我很好奇您不使用 Core Data 的原因。
  • 我通常使用一些围绕 SQLite 的包装器,或者现在经常使用 Core Data。但是我想知道如何直接使用该库,所以...

标签: iphone objective-c sqlite


【解决方案1】:

当然不会被插入。您需要调用 sqlite3_step 来实际执行您的语句。

签出the documentation

这是一个 SQLITE 的东西,而不是 iPhone 特定的东西。

来自文档:

在准备好的语句之后 使用任一准备 sqlite3_prepare_v2() 或 sqlite3_prepare16_v2() 或其中之一 遗留接口 sqlite3_prepare() 或 sqlite3_prepare16(),这个函数 必须调用一次或多次 评估语句。

【讨论】:

  • SQLite 文档的布局不是很好。谢谢指点。
  • ...但是是的,我遗漏了一些明显的东西。
【解决方案2】:

我会完全建议使用包装器而不是自己处理编译语句...这里提供了一个不错的选项列表:http://cocoaheads.byu.edu/resources/sqlite

【讨论】:

    【解决方案3】:

    您只在此处插入一行,因此有很多样板代码。想想如果你想插入多行会发生什么:

    • 您仍然需要一个准备语句
    • 您仍然需要一个 finalize 语句
    • 您需要为要添加的每一行添加一个步骤语句。您可以将“步骤”视为“执行”(或“获取下一行”,如果您正在查看 SELECT 语句)

    顺便说一句,如果准备好的语句失败,您可能不想“步进”。

    【讨论】:

      【解决方案4】:

      使用代码

      const char *sqlStatement = "REPLACE INTO  table (name, description, image) VALUES (?, ?, ?)";
      

      而不是“插入”

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-06
        • 1970-01-01
        • 2011-06-05
        • 2014-02-17
        • 1970-01-01
        • 1970-01-01
        • 2011-09-29
        • 1970-01-01
        相关资源
        最近更新 更多