Objective-C压缩几个SQL语句

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*

我有一个与SQL数据库对话的应用程序,示例表由OBSERVATIONSID(主键)、LEVEL0、LEVEL1、LEVEL2、LEVEL3、LEVEL4和EDITABLE组成

目前每次我想排一行,我 读取数据库以确保行不存在。 存储数据 再次读取数据库以获取刚刚添加的主键

存储数据

+ (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;
    }