【发布时间】:2013-11-21 12:48:31
【问题描述】:
我在 sqlite 数据库中有一个区域表。每次我只是对 sqlite 数据库执行插入操作。我如何检查是否存在任何记录。如果不存在,只需插入。如果存在则更新记录。
请帮帮我。
【问题讨论】:
我在 sqlite 数据库中有一个区域表。每次我只是对 sqlite 数据库执行插入操作。我如何检查是否存在任何记录。如果不存在,只需插入。如果存在则更新记录。
请帮帮我。
【问题讨论】:
您可以轻松地“插入或忽略到 tbl_name” 在这里你可以看到这个例子 http://www.raywenderlich.com/913/sqlite-tutorial-for-ios-making-our-app 这对你有用.... http://www.sqlite.org/lang_conflict.html
【讨论】:
是的,您可以通过一个查询来做到这一点。
INSERT ON CONFLICT IGNORE 应该对您有所帮助:http://www.sqlite.org/lang_conflict.html
在名称上设置唯一键,如果名称已存在,则在尝试插入记录时会产生冲突。
默认是ABORT,所以没有IGNORE,语句会返回错误。如果您不想这样,请使用 IGNORE。
【讨论】:
如果您的表上有主键,您可以使用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 替换了以前的值而不是插入第二条记录:
如果您没有主键,而不是这个简单的INSERT OR REPLACE,则必须将其分为两个步骤:
用SELECT寻找记录:如果找到,做UPDATE;如果找不到,请INSERT。
首先 DELETE 任何符合您想要的任何条件的记录,然后执行 INSERT。
第一种方法更安全一些,但如果必须,您可以使用第二种方法(尽管如果您有任何问题,您可能会使用事务并执行ROLLBACK)。不用说,INSERT OR REPLACE 方法更简单,但需要一个主键。
【讨论】:
第一次调用获取数据库中的记录查询。在这里我添加一个示例,我正在检查数据库中是否可用的用户登录信息。所以添加下面的代码。如果用户记录可用,则我得到记录数组,否则为零。
+(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,则必须调用更新查询,而不是数据库中没有记录,因此必须调用插入查询
【讨论】:
在我将所有更新导入另一个数据库表的情况下,我可以使用以下方法:
-- 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'。
【讨论】: