Objective-C压缩几个SQL语句
我有一个与SQL数据库对话的应用程序,示例表由OBSERVATIONSID(主键)、LEVEL0、LEVEL1、LEVEL2、LEVEL3、LEVEL4和EDITABLE组成 目前每次我想排一行,我 读取数据库以确保行不存在。 存储数据 再次读取数据库以获取刚刚添加的主键 存储数据Objective-C压缩几个SQL语句,objective-c,sqlite,ipad,Objective C,Sqlite,Ipad,我有一个与SQL数据库对话的应用程序,示例表由OBSERVATIONSID(主键)、LEVEL0、LEVEL1、LEVEL2、LEVEL3、LEVEL4和EDITABLE组成 目前每次我想排一行,我 读取数据库以确保行不存在。 存储数据 再次读取数据库以获取刚刚添加的主键 存储数据 + (void) ObservationsEditSaveData : (NSString*) Level1 : (NSString*) Level2 : (NSString*)Level3 : (NSString*
+ (void) ObservationsEditSaveData : (NSString*) Level1 : (NSString*) Level2 : (NSString*)Level3 : (NSString*) Level4 : (NSString*) Level0{
sqlite3_stmt *updateStmt;
sqlite3_open([dbObservationPathString UTF8String], &ObservationDB);
NSString* updateSQL = [NSString stringWithFormat: @"INSERT INTO OBSERVATIONS(LEVEL0, LEVEL1, LEVEL2, LEVEL3, LEVEL4, EDITABLE) values (?,?,?,?,?,?)"];
sqlite3_prepare_v2(ObservationDB, [updateSQL UTF8String], -1, &updateStmt, NULL);
if(sqlite3_step(updateStmt)==SQLITE_DONE)
{
sqlite3_bind_text(updateStmt, 1, [Level0 UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(updateStmt, 2, [Level1 UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(updateStmt, 3, [Level2 UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(updateStmt, 4, [Level3 UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(updateStmt, 5, [Level4 UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_int(updateStmt, 6, 0);
sqlite3_step(updateStmt);
sqlite3_finalize(updateStmt);
}
sqlite3_close(ObservationDB);
}
读取ID/检查是否存在。(在检查是否存在时,如果返回ID,我假设它存在)
我想做的是减少sql调用的数量,我可以将这些命令组合成一个吗
顺便说一句,如果我把代码弄乱了,请说,我不会生气的
感谢您在绑定值之前调用
sqlite3\u步骤(在if
子句中)。您必须首先绑定值,然后才使用sqlite3\u步骤执行SQL。只需将if
子句与sqlite3\u步骤一起删除即可
您可以更改observationsEditSaveData
方法,以便:
在step
函数之前调用bind
函数
让函数返回插入行的行id(零表示有错误)
检查所有SQLite调用的结果
符合(起始方法和带有小写字母的变量名)
这将产生:
+ (sqlite3_int64) observationsEditSaveData : (NSString*) level1 : (NSString*) level2 : (NSString*)level3 : (NSString*) level4 : (NSString*) level0 {
sqlite3_stmt *updateStmt;
if (sqlite3_open([dbObservationPathString UTF8String], &observationDB) != SQLITE_OK) {
NSLog(@"open failed");
return 0;
}
const char *updateSQL = "INSERT INTO OBSERVATIONS(LEVEL0, LEVEL1, LEVEL2, LEVEL3, LEVEL4, EDITABLE) values (?,?,?,?,?,?)";
if (sqlite3_prepare_v2(observationDB, updateSQL, -1, &updateStmt, NULL) != SQLITE_OK)
NSLog(@"prepare failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_text(updateStmt, 1, [level0 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind 1 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_text(updateStmt, 2, [level1 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind 2 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_text(updateStmt, 3, [level2 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind 3 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_text(updateStmt, 4, [level3 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind 4 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_text(updateStmt, 5, [level4 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind 5 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_int(updateStmt, 6, 0))
NSLog(@"bind 1 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_step(updateStmt) != SQLITE_DONE)
NSLog(@"step failed: %s", sqlite3_errmsg(observationDB));
sqlite3_finalize(updateStmt);
sqlite3_int64 rowid = sqlite3_last_insert_rowid(observationDB);
sqlite3_close(observationDB);
return rowid;
}
顺便说一句,您的observationGetID
方法可能应该使用sqlite3\u bind\u xxx
函数,就像您在observationsEditSaveData
中所做的那样。您永远不希望使用stringWithFormat
构建SQL。如果你发现这样的绑定值太麻烦了,考虑使用,这使得编写实的SQLite代码变得更容易。此外,通常建议只打开数据库一次,而不是每次方法调用都打开和关闭数据库。因此,我是否要执行sqlite3_步骤,然后执行所有绑定?然后是while(sqlite3_step(statement)==SQLITE_ROW){ReturnValue=sqlite3_column_int(statement,0)}我不清楚sqlite3_bind_文本和sqlite3_column_int是如何结合在一起的请参见下面的代码示例。总之,step函数将实际执行SQL。但很明显,在绑定值之前,您不希望执行SQL。所以先绑定到第一步,然后再绑定到第二步。在observationGetID
中,对于WHERE
子句的所有列,您需要sqlite3\u prepare\u v2
,sqlite3\u bind\u xxx
,然后让您的while(sqlite3\u步骤(语句)==SQLITE\u行)
使用sqlite3\u column\u xxx
检索列的循环。是的,这很有道理,我对做了什么感到困惑。有这么多不清楚的建议,有没有任何方法可以很容易地进行修改,因此,它会在添加之前检查尚未存在的行,我读过关于“如果不存在则插入”的内容,但在我的尝试中失败了completly@user1603332您可以先调用observationGetID
,查看是否有值,如果没有,然后调用您的observationsEditSaveData
。也许我不理解这个问题。不,我就是这么做的,但我想知道是否有一种方法可以将它合并到一个sql调用中,只是为了更好地编码。调用数据库查看它是否存在,如果不调用数据库将数据放入,最后再次调用数据库以获取我刚刚输入的数据的ID。@user1603332有插入或替换语法,但这是使用主键来决定的,在这里不适用。有些人可能倾向于(a)在桌子上放一个备用的唯一键;(b)只是插入(忽略它是否已经存在并生成错误),但我认为这不是好的做法。但是,在获取唯一ID方面,您不必重新选择。您只需调用(假设OBSERVATIONSID
定义为INTEGER主键自动递增
)。
+ (sqlite3_int64) observationsEditSaveData : (NSString*) level1 : (NSString*) level2 : (NSString*)level3 : (NSString*) level4 : (NSString*) level0 {
sqlite3_stmt *updateStmt;
if (sqlite3_open([dbObservationPathString UTF8String], &observationDB) != SQLITE_OK) {
NSLog(@"open failed");
return 0;
}
const char *updateSQL = "INSERT INTO OBSERVATIONS(LEVEL0, LEVEL1, LEVEL2, LEVEL3, LEVEL4, EDITABLE) values (?,?,?,?,?,?)";
if (sqlite3_prepare_v2(observationDB, updateSQL, -1, &updateStmt, NULL) != SQLITE_OK)
NSLog(@"prepare failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_text(updateStmt, 1, [level0 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind 1 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_text(updateStmt, 2, [level1 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind 2 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_text(updateStmt, 3, [level2 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind 3 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_text(updateStmt, 4, [level3 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind 4 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_text(updateStmt, 5, [level4 UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind 5 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_bind_int(updateStmt, 6, 0))
NSLog(@"bind 1 failed: %s", sqlite3_errmsg(observationDB));
if (sqlite3_step(updateStmt) != SQLITE_DONE)
NSLog(@"step failed: %s", sqlite3_errmsg(observationDB));
sqlite3_finalize(updateStmt);
sqlite3_int64 rowid = sqlite3_last_insert_rowid(observationDB);
sqlite3_close(observationDB);
return rowid;
}