我正在尝试NOT IN
选择NOT IN
列表是动态的。像
SELECT id, type FROM CONTACTS where type NOT IN ('connect','answer')
在代码中,我徒劳无功的尝试是:
db.query(TABLE, new String[] { "id", ""}, " type NOT IN (?)", "connect,answer",
null, null, null); // didn't work
db.query(TABLE, new String[] { "id", ""}, " type NOT IN (?)", "'connect','answer'",
null, null, null); // didn't work
我对此的看法是?
替换将我的逗号列表视为单个参数。我确实找到了一个解决方案,但它相当丑陋所以我不会在这里发布它,直到有人提出更优雅的东西
答案 0 :(得分:21)
你不能只放一个'?'而不是值列表。因此,尝试参数化列表几乎没有什么好处。当然,可以创建2,4,16值准备语句..." type NOT IN (?,?)", new String[]{ "connect","answer" },...
,但即使在具有远程RDBMS的服务器上,它也具有可疑价值。
相反,做
db.query(TABLE, new String[] { "id", ""}, " type NOT IN ('connect','answer')",
null, null, null, null);
如果列表是动态的,则必须转义字符串并将它们放入单引号列表中。
答案 1 :(得分:3)
您可以使用String.format动态设置参数。
例如:
db.query(TABLE, new String[] { "id", ""}, " type NOT IN (?)", "connect,answer", null, null, null);
=>
String argsArrayToString(List<String> args) {
StringBuilder argsBuilder = new StringBuilder();
argsBuilder.append("(");
final int argsCount = args.size();
for (int i=0; i<argsCount; i++) {
argsBuilder.append(args.get(i));
if (i < argsCount - 1) {
argsBuilder.append(",");
}
}
argsBuilder.append(")");
}
db.query(TABLE, new String[] { "id", ""}, String.format(" type NOT IN (%s)", argsArrayToString(arrays)), null, null, null, null);
答案 2 :(得分:1)
如果动态创建包含“not in”值列表的String,然后将它们附加到sql字符串的末尾,可以动态使用“not in”,如下所示:
public static Vector selectAllFormTypesForAccountIgnoringFormVersions(
int accountId, String formsIgnored) {
protected final static String selectAllFormTypesForAccountIgnoringFormVersions = "SELECT DISTINCT FormType.*"
+ " FROM FormType, Form WHERE Form.accountId=? AND FormType.formTypeContentId = Form.formTypeContentId"
+ " AND Form.formVersionId NOT IN (";
Vector allFormTypes = new Vector();
SQLiteDatabase db = null;
String[] selectionArgs = { Integer.toString(accountId)};
try {
DataManager_Platform dataManager = (DataManager_Platform) DataManager_Platform
.getDataManager();
db = (SQLiteDatabase) dataManager.getDatabase();
Cursor cursor = db.rawQuery(
selectAllFormTypesForAccountIgnoringFormVersions + formsIgnored + ")",
selectionArgs);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
FormType_Platform formType = new FormType_Platform();
formType.populateModel(cursor);
allFormTypes.add(formType);
cursor.moveToNext();
}
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
} finally {
try {
if (db != null) {
db.close();
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
return allFormTypes;
}