【问题标题】:SQLite iOS Insert dataSQLite iOS 插入数据
【发布时间】:2012-10-25 01:03:26
【问题描述】:

我试图在我的 sqlite 文件中只插入一个名称。我正在使用此代码,但它不起作用:/

-(void)InsertRecords:(NSMutableString *) txt{
    if(addStmt == nil) {
        const char *sql = "INSERT INTO myMovies (movieName)  VALUES(?) ";
        if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
            NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));
        else
            sqlite3_bind_text(addStmt, 1, [txt UTF8String], -1, SQLITE_TRANSIENT);
    }
    if(SQLITE_DONE != sqlite3_step(addStmt))

        NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database));
    else
        sqlite3_reset(addStmt);
}

【问题讨论】:

  • @adum 错误是:断言失败 -[MyDvDsList InsertRecords:], /Users/.../MyDvDsList.m:52 2012-10-25 02:00:54.916 MyDvDs[28287: 14003] *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“创建添加语句时出错。 '内存不足''
  • 当您收到“内存不足”错误时,这实际上意味着databasesqlite3 指针是NULL(通常是无法正确打开数据库的症状) .

标签: ios sqlite insert


【解决方案1】:

将您的查询传递给此方法并尝试,

-(void)Insertdata:(NSString*)query{

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:@"YourDBName.sql"];

    if(sqlite3_open([databasePath UTF8String],&db) == SQLITE_OK)
    {
        NSString *querySQL = [NSString stringWithFormat: @"%@",query];

        char *errmsg=nil;

        if(sqlite3_exec(db, [querySQL UTF8String], NULL, NULL, &errmsg)==SQLITE_OK)
        {
           NSLog(@".. Row Added ..");
        }
    }
    sqlite3_close(db);
}

【讨论】:

    【解决方案2】:

    来自 sqlite 的“内存不足”错误通常意味着您正在使用的数据库句柄尚未打开。确保使用您发布的代码中显示的database 变量调用sqlite3_open_v2

    【讨论】:

      【解决方案3】:

      好吧,我终于成功了!这是我为所有需要它的人使用的代码:

      -(void)InsertRecords:(NSMutableString *)txt{
      
          NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:@"movieData.sqlite"];
          const char *dbpath = [dbPath UTF8String];
          sqlite3 *contactDB;
      
          sqlite3_stmt    *statement;
      
          NSLog(@"%@",dbPath);
          if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
          {
              NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO myMovies (movieName) VALUES (\"%@\")", txt];
      
              const char *insert_stmt = [insertSQL UTF8String];
      
              sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
              if (sqlite3_step(statement) == SQLITE_DONE)
              {
                  sqlite3_bind_text(statement, 1, [txt UTF8String], -1, SQLITE_TRANSIENT);
              } else {
                  NSLog(@"error");
              }
              sqlite3_finalize(statement);
              sqlite3_close(contactDB);
          }
      }
      

      【讨论】:

      • 这是不正确的。首先,您将数据插入到包中的数据库中,该包是只读的。请改用 Documents 文件夹。其次,您正在使用stringWithFormat 构建SQL,但如果该值包含引号,则SQL 将失败。在 SQL 语句中始终使用 ? 占位符和 sqlite3_bind_XXX 与字符串值。第三,我通常建议在else 子句中记录sqlite3_errmsg,这样如果失败,您就会知道原因。第四,我建议不要每次都打开和关闭数据库。应用启动时打开数据库,终止时关闭。
      • 这对 SQL 注入攻击开放
      【解决方案4】:

      试试这个:

      //save our data
      - (BOOL) saveEmployee:(Employee *)employee
      {
          BOOL success = false;
          sqlite3_stmt *statement = NULL;
          const char *dbpath = [databasePath UTF8String];
      
          if (sqlite3_open(dbpath, &mySqliteDB) == SQLITE_OK)
          {
              if (employee.employeeID > 0) {
                  NSLog(@"Exitsing data, Update Please");
                  NSString *updateSQL = [NSString stringWithFormat:@"UPDATE EMPLOYEES set name = '%@', department = '%@', age = '%@' WHERE id = ?",
                                          employee.name,
                                          employee.department,
                                          [NSString stringWithFormat:@"%d", employee.age]];
      
                  const char *update_stmt = [updateSQL UTF8String];
                  sqlite3_prepare_v2(mySqliteDB, update_stmt, -1, &statement, NULL );
                  sqlite3_bind_int(statement, 1, employee.employeeID);
                  if (sqlite3_step(statement) == SQLITE_DONE)
                  {
                      success = true;
                  }
      
              }
              else{
                  NSLog(@"New data, Insert Please");
                  NSString *insertSQL = [NSString stringWithFormat:
                                         @"INSERT INTO EMPLOYEES (name, department, age) VALUES (\"%@\", \"%@\", \"%@\")",
                                         employee.name,
                                         employee.department,
                                         [NSString stringWithFormat:@"%d", employee.age]];
      
                  const char *insert_stmt = [insertSQL UTF8String];
                  sqlite3_prepare_v2(mySqliteDB, insert_stmt, -1, &statement, NULL);
                  if (sqlite3_step(statement) == SQLITE_DONE)
                  {
                      success = true;
                  }
              }
      
              sqlite3_finalize(statement);
              sqlite3_close(mySqliteDB);
      
          }
      
          return success;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-18
        • 2011-12-18
        • 1970-01-01
        • 1970-01-01
        • 2012-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多