SQL WHERE IN子句不起作用 - FMDB - 传递逗号分隔的字符串

时间:2012-07-17 17:03:42

标签: ios sqlite where fmdb clause

我搜索了所有问题,但还没有找到答案。我最接近的是Passing an array to sqlite WHERE IN clause via FMDB?。但是,建议的答案似乎不起作用。该命令不会抛出任何错误,但它也不会执行预期的操作(例如DELETE)。 这就是我想要做的事情:

[myDB executeUpdateWithFormat:@"DELETE FROM table WHERE row_id IN (%@)",rowIdsToBeDeleted];

rowIdsToBeDeleted是一个逗号分隔的NSString,其中包含rowIds作为NSNumber对象,例如

1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012

我甚至尝试过使用executeUpdate,但没有运气。 你们中的任何人可以帮忙吗?

2 个答案:

答案 0 :(得分:4)

你可以做到:

[myDB executeUpdate:[NSString stringWithFormat:@"DELETE FROM table WHERE row_id IN (%@)",rowIdsToBeDeleted]];

尽管人们可能会从方法名称推断,但executeUpdateWithFormat方法执行传统的printf样式格式化。在幕后,它真正做的是遍历格式字符串,用?占位符替换printf样式字符串,然后尝试使用适当的sqlite3_bind_xxx函数将值绑定到这些占位符。

executeUpdateWithFormat的这种实现引入了各种微妙的问题。 (因此,在将来的FMDB版本中可能会弃用它。)在这种特殊情况下,问题是sqlite3_bind_xxx无法将逗号分隔的字符串绑定为要绑定到单个{的值数组。 {1}}占位符。

通常应该避免使用?(或Swift字符串插值)来构建要传递给FMDB或SQLite的SQL语句,因为如果执行不当,您可能会遇到SQL注入攻击和/或如果失败则会失败正确转义字符串值。但是,此示例中,您要测试以查看某个数值是否在一组数值中,这是该规则的一个例外,您可以使用stringWithFormat,如上所示。

答案 1 :(得分:-2)

如果该方法类似于NSPredicate语法,只需删除括号(它们是为您处理的(并传入集合而不是字符串):

NSArray *ids = [rowIdsToBeDeleted componentsSeparatedByString:@","];
[myDB executeUpdateWithFormat:@"DELETE FROM table WHERE row_id IN %@",ids];

修改

此外,通常您传入一个实际的集合对象(不是字符串)...以上编辑以反映