4

在为我的应用程序构建搜索时,我在使用 FMDB SQLite Wrapper (https://github.com/ccgus/fmdb) 时遇到了问题。

当我用这个 SQL 命令搜索我的数据库时,一切都很好。返回了 13 个对象,我可以使用它们。

FMResultSet *rs = [db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE '%Daimler%'"];

但是当我尝试从用户输入中插入 searchQuery 时,如下所示:

FMResultSet *rs = [db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE (?)", theSearchQuery];

...该值不会插入到 SQL 命令中。而且我没有从数据库中得到任何返回的对象。即使字符串(theSearchQuery)与第一个示例中编写的相同。

另外,为了您的方便,我从 FMDB 的文档中发布了一部分。:)

Data Sanitization

在向 FMDB 提供 SQL 语句时,您不应尝试在插入之前“清理”任何值。相反,您应该使用标准的 SQLite 绑定语法:

INSERT INTO myTable VALUES (?, ?, ?) ? SQLite 将字符识别为要插入的值的占位符。执行方法都接受可变数量的参数(或这些参数的表示,例如 NSArray 或 va_list),这些参数为您正确转义。

因此,您不应该这样做(或类似的事情):

[db executeUpdate:[NSString stringWithFormat:@"INSERT INTO myTable VALUES (%@)", @"this has \"很多'奇怪的\"引号'"]]; 相反,你应该这样做:

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @"this has \"很多'奇怪的\"引号'"]; 提供给 -executeUpdate: 方法(或任何接受 va_list 作为参数的变体)的所有参数都必须是对象。以下将不起作用(并将导致崩溃):

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", 42]; 插入数字的正确方法是将其装箱到 NSNumber 对象中:

[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]]; 或者,您可以使用 -execute*WithFormat: 变体来使用 NSString 样式的替换:

[db executeUpdateWithFormat:@"INSERT INTO myTable VALUES (%d)", 42]; 在内部, -execute*WithFormat: 方法为您正确地装箱。可识别以下百分比修饰符:%@、%c、%s、%d、%D、%i、%u、%U、%hi、%hu、%qi、%qu、%f、%g、% ld、%lu、%lld 和 %llu。使用其他修饰符将产生不可预知的结果。如果由于某种原因需要 % 字符出现在 SQL 语句中,则应使用 %%。

4

2 回答 2

7
NSString *search_text = [NSString stringWithFormat:@"%%%@%%", theSearchQuery];

FMResultSet *rs = [db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE ?", search_text];
于 2011-08-19T22:14:11.340 回答
4

我强烈建议避免使用 stringWithFormat 创建查询:!FMDB 试图强迫您使用他们的数据清理是有充分理由的。但是,由于 FMDB 正在对您的输入进行装箱,因此不需要以下代码中的括号,这可能会导致您的问题。

[db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE (?)", theSearchQuery];

简单地添加参数而无需任何括号,因为您永远不知道 FMDB 如何在内部封装您的参数。

[db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE ?", theSearchQuery];

如果这仍然不起作用,请尝试使用建议的 executeQueryWithFormat: FMDB 方法:

[db executeQueryWithFormat:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE %@", theSearchQuery];
于 2011-07-24T16:23:27.367 回答