2012-07-17 78 views
2

我已经搜遍了所有问题,但是还没有找到答案。我最接近的是Passing an array to sqlite WHERE IN clause via FMDB?。但是,答案似乎并不奏效。该命令不会引发任何错误,但它不会执行预期的操作(例如,DELETE)。 这里就是我想要做的事:SQL WHERE IN子句不起作用 - FMDB - 传递逗号分隔字符串

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

rowIdsToBeDeleted是一个逗号分隔包含的rowid为NSNumber的对象,例如的NSString

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

我甚至尝试过使用executeUpdate,但没有运气。 请问你们能帮忙吗?

回答

-2

如果这个方法就像是NSPredicate语法什么,只是去掉括号(他们为您处理(并通过一个集合,而不是字符串)中:

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

编辑

而且,通常你传递一个实际的集合对象(不是字符串)......上述编辑,以反映

+0

我发送一个包含CS NSNumber对象的NSString(它不像NSPredicate /发送NSNumbers,因为ints在FMDB上不起作用)。然而,我试过你的解决方案,它给出了以下错误(FMDB错误代码1,语法错误):'near“?”:语法错误“ – Subzero 2012-07-17 17:17:40

+0

谢谢,我也会尝试。然而,其他人发布了另外一个解决方案,但是他猜测他删除了这个解决方案。感谢他,下面的工作就像一个魅力: – Subzero 2012-07-17 17:27:53

+0

不得不downvote这个,因为它根本不会工作。 – 2013-08-15 16:15:10

4

你可以做简单:

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

尽管人们可能以其他方式从方法名推断,该executeUpdateWithFormat方法做执行传统的printf样式的格式。在幕后,它实际上是遍历格式化字符串,用?占位符替换printf样式的字符串,然后尝试合适的sqlite3_bind_xxx函数将值绑定到这些占位符。

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

一般应避免使用stringWithFormat(或雨燕字符串插值)来构建要传递给FMDB或SQLite的SQL语句,因为如果处理不适当,你可以接触到SQL注入攻击和/或如果您无法正常逃脱失败字符串值。但是,在这个例子中,如果您想测试某个数字值是否在一组数值内,则该规则是例外情况,您可以使用stringWithFormat,如上所示。

+0

executeUpdateWithFormat实际上与将格式化的字符串传递给executeUpdate不同。不幸。尝试了以前的变体,它没有工作,因为它试图将所有东西都转换为SQL绑定。 – Tony 2012-11-10 02:32:23

+0

简单的NSString stringWithFormat确实有效。我可以证实这一点。 – Tony 2012-11-10 22:14:21

+0

executeUpdateWithFormat与executeUpdate不同的原因是变量替换是由SQLite完成的,它会清理输入,所以包含逗号的字符串不会被视为多个值,而是一个带有逗号的大字符串值。 – charles 2015-06-12 16:10:26