Ios 如何在sqlite查询中从NSString中删除

Ios 如何在sqlite查询中从NSString中删除,ios,objective-c,xcode,sqlite,Ios,Objective C,Xcode,Sqlite,试图从这句话中删除“嘿,我明天来”。通过重复替换字符串也尝试了字符串,但它不起作用。请帮我找到解决办法,因为我已经在这上面浪费了半天多的时间了。下面是我尝试的查询和输出,请检查 NSMutableString *msql = [[NSMutableString alloc] initWithFormat:@"insert into %@ ", tableName]; for (int i=0; i<[arrArguments count]; i++){

试图从这句话中删除“嘿,我明天来”。通过重复替换字符串也尝试了字符串,但它不起作用。请帮我找到解决办法,因为我已经在这上面浪费了半天多的时间了。下面是我尝试的查询和输出,请检查

 NSMutableString *msql = [[NSMutableString alloc] initWithFormat:@"insert into %@ ", tableName];
        for (int i=0; i<[arrArguments count]; i++){
            NSMutableArray *marrArgum = [arrArguments objectAtIndex:i];

            if (i==0){
[msql appendFormat:@"SELECT '%@' AS 'id', '%@' AS 'UserID', '%@' AS 'MessageID', '%@' AS 'ActualMessage', '\%@\' AS 'MessageType', '%@' AS 'MessageIsOld', '%@' AS 'MessageSentBySelf', '%@' AS 'Timestamp', '%@' AS 'MessageRead', '%@' AS 'MessageToUser' ", [marrArgum objectAtIndex:0], [marrArgum objectAtIndex:1], [marrArgum objectAtIndex:2], [marrArgum objectAtIndex:3], [marrArgum objectAtIndex:4], [marrArgum objectAtIndex:5], [marrArgum objectAtIndex:6], [marrArgum objectAtIndex:7], [marrArgum objectAtIndex:8], [marrArgum objectAtIndex:9]];

}
            else{
                [msql appendFormat:@"UNION ALL SELECT '%@', '%@', '%@', '\%@\', '%@', '%@', '%@', '%@', '%@', '%@' ", [marrArgum objectAtIndex:0], [marrArgum objectAtIndex:1], [marrArgum objectAtIndex:2], [marrArgum objectAtIndex:3], [marrArgum objectAtIndex:4], [marrArgum objectAtIndex:5], [marrArgum objectAtIndex:6], [marrArgum objectAtIndex:7], [marrArgum objectAtIndex:8], [marrArgum objectAtIndex:9]];
            }

NSString *sql = [NSString stringWithFormat: @"%@", msql];
DBLog(@"INSERT SQL QUERY: %@", sql);
        METHOD_CALLER;
        int intQcheck = sqlite3_exec(sqliteDB, [sql UTF8String], NULL, NULL, &err);
        DBLog(@"intQcheck = %d", intQcheck);
        if (intQcheck!= SQLITE_OK) {
            if ([self targetAppIsUsingDevProfile])
                NSAssert(0, @"Error in Insertion Query(intQcheck=%d): %@", intQcheck, strMsql);
            success = NO;
        }
但它不起作用。输出仍与之前相同,即:

i’ll see u you
请导游。谢谢。

为什么准备好的声明会受到青睐

当您自己将SQL查询创建为字符串时,它们几乎总是包含用户输入的一部分。攻击者可以利用这一点,例如,使用“”巧妙地更改查询的语义,从而获得对数据的未经授权访问或销毁数据

这称为SQL注入,是最严重的安全风险之一,请参见此处:

防卫

将准备好的语句与变量绑定(又称参数化查询)结合使用是所有开发人员首先应该学习如何编写数据库查询的方式

如何在SQLite和iOS中使用准备好的语句

有关准备好的声明,请参见

基本步骤是:

创建准备好的语句 将值绑定到参数 运行SQL 销毁对象以避免资源泄漏 下面是一个简单的例子:

-(BOOL)insertValue:(NSString *)value intoDB:(sqlite3 *)db {
    sqlite3_stmt *stmt = NULL;
    NSString *insertStmt = @"insert into SomeTable (sometext) values (?)";
    //create the prepared statement
    if(SQLITE_OK == sqlite3_prepare_v2(db, insertStmt.UTF8String, -1, &stmt, NULL)) {
        //bind values to parameters
        if(SQLITE_OK == sqlite3_bind_text(stmt, 1, value.UTF8String, -1, SQLITE_STATIC)) {
            //run the SQL
            if(SQLITE_DONE != sqlite3_step(stmt)) {
                return NO;
            }
        }
        else {
            return NO;
        }
        //destroy the object to avoid resource leaks
        sqlite3_finalize(stmt);
    }
    else {
        return NO;
    }
    return YES;
}
它将被称为您的示例字符串我将看到您这样:

sqlite3 *db;
if(SQLITE_OK == sqlite3_open(dbURL.absoluteString.UTF8String, &db)) {
    NSString *someValue = @"i'll see u you";
    if (![self insertValue:someValue intoDB:db]) {
        NSLog(@"insert failed: '%s'", sqlite3_errmsg(db));
    }
    sqlite3_close(db);
}
else {
    NSLog(@"open db failed: '%s'", sqlite3_errmsg(db));
}
因此,在这里使用“例如,来自用户输入的”不会造成任何伤害,因为我们使用的是预先准备好的语句

演示

如果查看数据库实用程序中的数据,则在insert语句之后如下所示:


替换为空字符串而不是\'?相同的输出没有变化'!='怎么样。一个是直的,另一个是弯的。这不是同一个字符。如果这样做,在替换时也复制相同的字符并粘贴到代码中,但不起作用。SQL语句与字符替换有什么关系?这两件事似乎与我完全无关。顺便说一句,答案末尾的你应该是实际答案。任何人都不应该使用字符串格式构建SQL查询。只使用准备好的语句。让底层SQLite API根据需要进行适当的引用和转义。这是SQL注入攻击的主要原因。@rmaddy您是对的,我不仅应该在回答的最后用一句话简单地提到这一点,而且明确指出这一点非常重要。我已经创建了一个小示例,并相应地重写了我的答案。@StephanSchlecht我的要求有点不同,所以我想我需要粘贴更多有问题的代码,以便清楚地理解。请再次检查我的问题,因为有几位评论员提到过,出于安全原因,不建议将SQL组装为字符串。再看一看我的例子,阅读参考文本。这需要适当的引用和转义。也就是说,如果要转义“以便在输出中显示为\”,则必须在替换中使用\',因此需要使用stringByReplacingOccurrencesOfString:@'with string:\\\']
sqlite3 *db;
if(SQLITE_OK == sqlite3_open(dbURL.absoluteString.UTF8String, &db)) {
    NSString *someValue = @"i'll see u you";
    if (![self insertValue:someValue intoDB:db]) {
        NSLog(@"insert failed: '%s'", sqlite3_errmsg(db));
    }
    sqlite3_close(db);
}
else {
    NSLog(@"open db failed: '%s'", sqlite3_errmsg(db));
}