【问题标题】:SQLite using FMDB: Insert record not working/ no such table使用 FMDB 的 SQLite:插入记录不起作用/没有这样的表
【发布时间】:2014-11-05 15:38:43
【问题描述】:

请帮我找出问题所在。

插入语句不起作用,当我检查保存在 /Users/jppangilinan/Library/Application Support/iPhone Simulator/ 4.3/Applications/61BBA03F-C240-414D-9A64-6CE3B34DF9C2/Documents/person.sqlite3 似乎保存在该位置的数据库没有任何表,这就是插入语句不起作用的原因。为什么它没有在我的项目的资源文件夹中复制我的 sqlite db? TIA

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docsPath = [paths objectAtIndex:0];
    NSString *path = [docsPath stringByAppendingPathComponent:@"person.sqlite3"];

FMDatabase *database = [FMDatabase databaseWithPath:path];
[database open];

[database beginTransaction];

NSString *query = [NSString stringWithFormat:@"insert into person(rowid,fname,lname,address) values (null, '%@','%@','%@')",fname.text,lname.text,address.text];

NSLog(@" %@",path);
NSLog(@" %@",query);

BOOL y= [database executeUpdate:query];

if (!y)
{
    NSLog(@"insert failed!!");
}

NSLog(@"Error %d: %@", [database lastErrorCode], [database lastErrorMessage]);



[database commit];
[database close];

}

【问题讨论】:

  • 你找到解决这个问题的方法了吗?

标签: ios xcode sqlite xcode3.2


【解决方案1】:

为了在应用程序的 Documents 文件夹中访问您的资源数据库,您首先需要在应用程序启动时将其复制到那里。

如果数据库文件在你的 xcode 项目的资源文件夹中,它不会自动复制到应用程序的文档目录中。

为此,您可以使用:

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

NSError *error;

NSString *databasePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"person.sqlite3"];

[[NSFileManager defaultManager] copyItemAtPath:databasePath 
                                                toPath:[NSString stringWithFormat:@"%@/%@",documentsDirectory,@"person.sqlite3"]
                                                 error:&error];

您将能够使用现有代码访问现在位于文档文件夹中的数据库。

发生的情况是,由于未复制现有 DB 文件,当您调用 databaseWithPath 时会创建一个新的空文件,这就是您收到 Error 1: no such table: person 错误的原因。

来自FMDB documentation

数据库创建

使用 SQLite 数据库文件的路径创建 FMDatabase。这个 路径可以是以下三个之一:

文件系统路径。该文件不必存在于磁盘上。如果它 不存在,它是为您创建的。 一个空字符串 (@"")。在临时位置创建一个空数据库。这个数据库是用 FMDatabase 连接删除的 关闭。

空。创建内存数据库。该数据库将 FMDatabase 连接被销毁。

FMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];

【讨论】:

    【解决方案2】:

    需要注意的事项:

    • 看看使用参数(?在 sqlite 而不是 stringWithFormat)
    • 您需要检查错误代码:大多数函数返回 bool。数据库也有 lastErrorCode (int)、lastErrorMessage (NSString) 和 hadError (bool)。检查并记录这些内容。
    • 对于 uniqueId,您正在插入一个 const 11。看起来并不唯一。如果自动播种 id,请检查 lastInsertedRowId 并且不要在插入语句中指定 id。 http://www.sqlite.org/autoinc.html

    https://github.com/ccgus/fmdb/blob/master/src/FMDatabase.h

    示例: https://github.com/ccgus/fmdb/blob/master/src/fmdb.m

    【讨论】:

    • 感谢 bryanmac,将检查可能的代码并感谢您提供的信息链接! =)
    • 这是我更新的代码。但它返回“错误 1:没有这样的表:人”
    • NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docsPath = [paths objectAtIndex:0]; NSString *path = [docsPath stringByAppendingPathComponent:@"person.sqlite3"]; FMDatabase *database = [FMDatabase databaseWithPath:path]; if (![数据库打开]) { NSLog(@"无法打开数据库。"); } NSLog(@"错误 %d: %@", [数据库 lastErrorCode], [数据库 lastErrorMessage]); [数据库 executeUpdate:@"插入人 (uniqueId,fname) 值(?,?)",[NSNumber numberWithInt:11],@"Paul",nil];
    • NSLog(@"错误 %d: %@", [数据库 lastErrorCode], [数据库 lastErrorMessage]); [数据库关闭];
    • 您应该在您的问题中添加一个“编辑:”部分以及其他代码和信息。在评论中很难阅读
    【解决方案3】:

    试试这个,开始事务并提交:

    FMDatabase *database = [FMDatabase databaseWithPath:path];
    [database open];
    
    [database beginTransaction];
    
    NSString *query = [NSString stringWithFormat:@"insert into person(uniqueId,fname) values (%d, '%@')",11,@"Paul"];
    
    NSLog(@" %@",path);
    
    BOOL y= [database executeUpdate:query];
    
    if (!y)
    {
        NSLog(@"insert failed!!");
    }
    
    [database commit];
    [database close];
    

    在这部分代码执行后,打开'nslog'打印路径中的sqlite文件 路径将是这样的: /Users/**/Library/Application Support/iPhone Simulator/4.3/Applications/person.sqlite3

    任何帮助恢复

    谢谢

    【讨论】:

    • 在交易中包装会给您带来什么?在 sqlite 中,单个语句隐含在事务中。
    • 嗨 Nagaraja Sathe,我使用了你的代码。但是它返回“插入失败”。我确实使用这个 NSLog(@"Error %d: %@", [database lastErrorCode], [database lastErrorMessage]); 检查了最后一个错误。错误1:没有这样的表:我确实检查了我的数据库并且我确定我上面有一个人表。
    • 我已经检查了 sqlite 数据库的路径位置。 /Users/jppangilinan/Library/Application Support/iPhone Simulator/4.3/Applications/61BBA03F-C240-414D-9A64-6CE3B34DF9C2/Documents/person.sqlite3 中的副本似乎没有任何表格???
    • 但是当我在 xcode 中检查可能 person.sqlite3 时,它保存在 RESOURCES 中,它有一个表和数据。
    • 您是手动还是通过编程方式将数据插入到 sqlite 中?
    【解决方案4】:

    您的“/Users/jppangilinan/Library/Application Support/iPhone Simulator/4.3/Applications/61BBA03F-C240-414D-9A64-6CE3B34DF9C2/Documents/person.sqlite3”中的副本可能与您在加载数据库的位置。在 Xcode 中右键单击您的数据库并查看获取信息。如果此数据库是您希望 exode 从中读取的数据库(好的数据库),请将其复制以替换 '/Users/jppangilinan/Library/Application Support/iPhone Simulator/4.3/Applications/.../Documents/ 上的数据库人.sqlite3'。我遇到了类似的问题。

    【讨论】:

      【解决方案5】:

      我有同样的问题,我通过以下代码解决了这个问题,添加此代码并将您的数据库路径保存在 _dbPath 中:

      - (void) FMDBInitializer{
      NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
      NSString *documentDir = [documentPaths objectAtIndex:0];
      NSString *databasePath = [documentDir stringByAppendingPathComponent:DATABASENAME];
      
      NSLog(@"%@",databasePath);
      
      BOOL success;
      
      NSFileManager *fileManager = [NSFileManager defaultManager];
      
      success = [fileManager fileExistsAtPath:databasePath];
      
      self._dbPath = databasePath;
      
      if(!success){
          NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:DATABASENAME];
          [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
      
          //self._db = [FMDatabase databaseWithPath:databasePath];
      }
      else {
          //self._db = [FMDatabase databaseWithPath:databasePath];
      }
      

      }

      并在您的每个查询中添加这一行代码:

      FMDatabase *database = [FMDatabase databaseWithPath:self._dbPath];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-21
        • 1970-01-01
        • 2012-06-13
        • 1970-01-01
        • 2012-10-16
        • 2013-03-07
        • 1970-01-01
        相关资源
        最近更新 更多