【问题标题】:How to check and then insert in sqlite?如何检查然后插入sqlite?
【发布时间】:2013-11-21 12:48:31
【问题描述】:

我在 sqlite 数据库中有一个区域表。每次我只是对 sqlite 数据库执行插入操作。我如何检查是否存在任何记录。如果不存在,只需插入。如果存在则更新记录。

请帮帮我。

【问题讨论】:

标签: ios sqlite


【解决方案1】:

您可以轻松地“插入或忽略到 tbl_name” 在这里你可以看到这个例子 http://www.raywenderlich.com/913/sqlite-tutorial-for-ios-making-our-app 这对你有用.... http://www.sqlite.org/lang_conflict.html

【讨论】:

    【解决方案2】:

    是的,您可以通过一个查询来做到这一点。

    INSERT ON CONFLICT IGNORE 应该对您有所帮助:http://www.sqlite.org/lang_conflict.html

    在名称上设置唯一键,如果名称已存在,则在尝试插入记录时会产生冲突。

    默认是ABORT,所以没有IGNORE,语句会返回错误。如果您不想这样,请使用 IGNORE。

    【讨论】:

      【解决方案3】:

      如果您的表上有主键,您可以使用INSERT OR REPLACE。例如:

      sqlite3 *database = NULL;
      
      NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
      NSString *path = [documentsPath stringByAppendingPathComponent:@"test.sqlite"];
      
      int rc = sqlite3_open([path UTF8String], &database);
      NSAssert(rc == SQLITE_OK, @"Open failed");
      
      // note, use PRIMARY KEY when creating table
      
      rc = sqlite3_exec(database, "CREATE TABLE IF NOT EXISTS test (animal TEXT PRIMARY KEY, sound TEXT)", NULL, NULL, NULL);
      NSAssert(rc == SQLITE_OK, @"Create failed: %s", sqlite3_errmsg(database));
      
      // create a record that will be replaced by the subsequent `INSERT OR REPLACE`
      
      rc = sqlite3_exec(database, "INSERT INTO test (animal, sound) VALUES ('dog', 'meow')", NULL, NULL, NULL);
      NSAssert(rc == SQLITE_OK, @"INSERT failed: %s", sqlite3_errmsg(database));
      
      // this will REPLACE entry if value with same PK found, otherwise it would INSERT
      
      rc = sqlite3_exec(database, "INSERT OR REPLACE INTO test (animal, sound) VALUES ('dog', 'woof')", NULL, NULL, NULL);
      NSAssert(rc == SQLITE_OK, @"INSERT failed: %s", sqlite3_errmsg(database));
      
      // now retrieve values and make sure it worked like we thought it would
      
      sqlite3_stmt *statement = NULL;
      rc = sqlite3_prepare_v2(database, "SELECT animal, sound FROM test", -1, &statement, NULL);
      NSAssert(rc == SQLITE_OK, @"prepare SELECT failed: %s", sqlite3_errmsg(database));
      
      while ((rc = sqlite3_step(statement)) == SQLITE_ROW) {
          const unsigned char *animal = sqlite3_column_text(statement, 0);
          const unsigned char *sound  = sqlite3_column_text(statement, 1);
          NSLog(@"%s goes %s", animal, sound);
      }
      NSAssert(rc == SQLITE_DONE, @"step failed: %s", sqlite3_errmsg(database));
      
      sqlite3_finalize(statement);
      
      sqlite3_close(database);
      

      这将报告INSERT OR REPLACE 替换了以前的值而不是插入第二条记录:

      2013-11-21 08:59:25.285 AnimalSounds[53549:70b] 狗去汪汪

      如果您没有主键,而不是这个简单的INSERT OR REPLACE,则必须将其分为两个步骤:

      1. SELECT寻找记录:如果找到,做UPDATE;如果找不到,请INSERT

      2. 首先 DELETE 任何符合您想要的任何条件的记录,然后执行 INSERT

      第一种方法更安全一些,但如果必须,您可以使用第二种方法(尽管如果您有任何问题,您可能会使用事务并执行ROLLBACK)。不用说,INSERT OR REPLACE 方法更简单,但需要一个主键。

      【讨论】:

        【解决方案4】:

        第一次调用获取数据库中的记录查询。在这里我添加一个示例,我正在检查数据库中是否可用的用户登录信息。所以添加下面的代码。如果用户记录可用,则我得到记录数组,否则为零。

         +(NSArray*)getTBL_LOGIN
        {
            NSMutableArray *Favourite=[[NSMutableArray alloc]init];
        
         sqlite3 *database;
        
         TabBarAppDelegate *x=(TabBarAppDelegate*)[[UIApplication sharedApplication]delegate];
        if(sqlite3_open([[x dataBasePath] UTF8String],&database) == SQLITE_OK) {
            NSString *str = [NSString stringWithFormat:@"select * from tbl_login"];
            const char *sqlStmt=[str UTF8String];             
            sqlite3_stmt *compiledStmt;                           
            if(sqlite3_prepare_v2(database, sqlStmt, -1, &compiledStmt, NULL) == SQLITE_OK) {
            while(sqlite3_step(compiledStmt)==SQLITE_ROW) 
                    {
                        NSString *uid=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStmt, 0)];
        
                        NSString *username=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStmt, 1)];
        
        
                        NSDictionary *d=[NSDictionary dictionaryWithObjectsAndKeys:uid,@"uid",username,@"username",nil];
                [Favourite addObject:d];
            }
            }
            sqlite3_finalize(compiledStmt);
        }
        sqlite3_close(database);
        
        if([Favourite count]>0)
        {
            NSArray *ar=[NSArray arrayWithArray:Favourite];
            return ar;
        } else {
            return nil;
        }
        }
        

        如果记录数 >=1,则记录存在,因此如果记录数为 0,则必须调用更新查询,而不是数据库中没有记录,因此必须调用插入查询

        【讨论】:

          【解决方案5】:

          在我将所有更新导入另一个数据库表的情况下,我可以使用以下方法:

          -- Existing table: t(uc UNIQUE, v1, v2, v3);
          -- Updates table: ut(uc UNIQUE, v2);
          INSERT OR REPLACE INTO t
              SELECT ut.uc, et.v1, ut.v2, et.v3 FROM ut
              LEFT JOIN t AS et ON ut.uc=et.uc;
          

          此语句会将来自ut 的新行插入t。现有行被替换为包含来自ut 的新数据和来自t 的现有数据的行。

          为此,您必须有一个 UNIQUE 列(这在您查找行更新或插入新行时很有意义),并且有可用的新数据以便可以查询(在相同或另一个数据库)。

          这对我有用,希望它可以帮助你。

          另一种可能具有更好性能的解决方案是使用两个语句:

           UPDATE t SET v1='some value', v2=123 WHERE unique_col='some_id';
           INSERT OR IGNORE t(v1, v2, unique_col) VALUES('some value', 123, 'some_id');
          

          UPDATE 将在找不到'some_id' 时变为空操作。 INSERT 将忽略所有存在的'some_id'

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-04-27
            • 1970-01-01
            • 1970-01-01
            • 2011-09-08
            • 2022-01-13
            • 1970-01-01
            • 2014-01-04
            相关资源
            最近更新 更多