Objective c fmdb-使用like选择查询以避免sql注入
大家好,祝大家圣诞快乐 我正在使用sqlite和fmdb作为包装器构建一个iOS应用程序。 我正在尝试执行以下sql语句:Objective c fmdb-使用like选择查询以避免sql注入,objective-c,ios,sqlite,fmdb,Objective C,Ios,Sqlite,Fmdb,大家好,祝大家圣诞快乐 我正在使用sqlite和fmdb作为包装器构建一个iOS应用程序。 我正在尝试执行以下sql语句: SELECT * FROM TABLE WHERE FIELD LIKE '%text%' 文本来自UISearchBar 到目前为止,我让它工作的唯一方法是使用以下代码: NSString *query = [NSString stringWithFormat:@"SELECT * FROM TABLE WHERE FIELD LIKE '%%%@%%'", text]
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]];
或者类似于:
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子句(“%%?%%”)周围的单引号或单引号而不是双引号,也会发生同样的情况
你能告诉我这个问题吗?
任何帮助都将不胜感激
新年快乐 您上次的尝试(没有任何引号)是正确的语法。您是否正在检查结果
是否为非零
?如果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
转义%
,\uuu
,以及通配符本身。因此:
- (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]];
}
通过这种方式,您可以搜索任何字符串,包括带有多字符通配符的字符串,/
,或带有单字符通配符的字符串,\u
您上次尝试(没有任何引号)的语法是正确的。您是否正在检查结果
是否为非零
?如果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
转义%
,\uuu
,以及通配符本身。因此:
- (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]];
}
通过这种方式,您可以搜索任何字符串,包括带有多字符通配符的字符串,
/
,或带有单字符通配符的字符串,\uu
+1我很高兴您能正确处理这一事实。太多人使用用户提供的字段轻松地使用stringWithFormat
构建SQL,而不考虑在用户字段中意外或故意使用引号字符。无论何时使用用户提供的数据,都应使用?
占位符。在太多的应用程序中,搜索乔的“鱼屋”是有问题的。+1我喜欢你能正确处理这个事实。太多人使用用户提供的字段轻松地使用stringWithFormat
构建SQL,而不考虑在用户字段中意外或故意使用引号字符。无论何时使用用户提供的数据,都应使用?
占位符。在太多的应用程序中,搜索Joe的“鱼屋”是有问题的。非常感谢Rob!这两个建议(逃脱或不逃脱)对我都有好处!谢谢你的彻底回答,罗布!这两个建议(逃脱或不逃脱)对我都有好处!Thanx也提供了完整的答案