sqlite 使用fmdb时,选择带有like的查询以避免SQL注入

v9tzhpje  于 2023-01-02  发布在  SQLite
关注(0)|答案(1)|浏览(175)

我正在使用SQLite和fmdb作为 Package 器构建iOS应用程序。我正在尝试执行以下SQL语句:

SELECT * FROM TABLE WHERE FIELD LIKE '%text%'

文本来自UISearchBar。
到目前为止,我让它工作的唯一方法是使用以下代码:

NSString *query = [NSString stringWithFormat:@"SELECT * FROM TABLE WHERE FIELD LIKE '%%%@%%'", text];
FMResultSet *results = [db executeQuery:query];

请注意,我只张贴查询代码。它工作得很好。
我想要的是避免SQL注入,所以我尝试这样做:

NSString *query = @"SELECT * FROM TABLE WHERE FIELD LIKE %%?%%";
FMResultSet *results = [db executeQuery:query, text];

或者类似于:

NSString *query = @"SELECT * FROM TABLE WHERE FIELD LIKE ?";
FMResultSet *results = [db executeQuery:query, [NSString stringWithFormat:@"%%%@%%", text]];

这不起作用。在like子句(' %?%')周围使用单引号或使用单%代替双%时也会发生同样的情况。
你能给我讲讲这个问题吗?

dfddblmv

dfddblmv1#

您上次尝试(不带引号)的语法是正确的。您是否正在检查results是否为非nil?如果为nil,则应检查错误字符串。例如,以下代码有效:

NSString *searchString = @"larry";
NSString *likeParameter = [NSString stringWithFormat:@"%%%@%%", searchString];
NSString *sql = @"SELECT text_column FROM test WHERE text_column LIKE ?";

FMResultSet *results = [db executeQuery:sql, likeParameter];

if (!results)
{
    NSLog(@"error: %@", [db lastErrorMessage]);
    [db close];
    return;
}

while ([results next])
{
    NSLog(@"%s: %@", __FUNCTION__, results[0]);
}

[results close];
[db close];

顺便说一下,如果您比较特别,并且不希望最终用户操纵参数或得到不直观的响应(并且您不希望最终用户应用他们自己的通配符),您可能希望使用ESCAPE SQL语法对出现的通配符(如%_)进行转义。您可能需要为转义字符定义一个常量:

NSString * const kEscapeCharacter = @"\\";

然后,构建SQL,如下所示:

NSString *likeParameter = [NSString stringWithFormat:@"%%%@%%", [self escapedLikeParameter:searchString]];
NSString *sql = [NSString stringWithFormat:@"SELECT text_column FROM test WHERE text_column LIKE ? ESCAPE '%@'", kEscapeCharacter];

其中escapedLikeParameter转义%_和通配符本身。

- (NSString *)escapedLikeParameter:(NSString *)string
{
    NSString *escapedString;
    escapedString = [string stringByReplacingOccurrencesOfString:kEscapeCharacter
                                                                withString:[NSString stringWithFormat:@"%@%@", kEscapeCharacter, kEscapeCharacter]];
    escapedString = [escapedString stringByReplacingOccurrencesOfString:@"_"
                                                             withString:[NSString stringWithFormat:@"%@_", kEscapeCharacter]];
    return [escapedString stringByReplacingOccurrencesOfString:@"%"
                                                    withString:[NSString stringWithFormat:@"%@%%", kEscapeCharacter]];
}

这样,您就可以搜索任何字符串,包括带有多字符通配符/或单字符通配符_的字符串。

相关问题