【问题标题】:Android Sqlite IN, NOT IN syntaxAndroid Sqlite IN,NOT IN 语法
【发布时间】:2011-01-16 18:55:28
【问题描述】:

我正在尝试运行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

我对此的看法是 ? 替换将我的逗号列表视为单个参数。我确实找到了一个解决方案,但它相当难看,所以我不会在这里发布它,直到有人提出更优雅的东西

【问题讨论】:

    标签: android sql sqlite


    【解决方案1】:

    你不能只放一个'?'而不是一个值列表。因此,尝试对列表进行参数化几乎没有什么好处。当然,可以创建 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);
    
    如果列表是动态的,您将不得不转义字符串并将它们放入单引号列表中。

    【讨论】:

    • 如果有问题的字符串来自您提供的列表而不是用户提供的列表,那么您可以知道它们是安全的,甚至不必转义它们(除非它们包含')。
    • 这就是我最终得到的解决方案。希望有一个小技巧,但我猜没有。还是想等一下看看有没有替代的建议
    • 对 Hibernate Criteria 比较熟悉,其 IN 得到很好的支持,但在 Android SDK 中找不到任何等效项。
    【解决方案2】:

    您可以使用 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);
    

    【讨论】:

    • 在将列表转换为字符串时不要添加“(”和“)”
    【解决方案3】:

    如果您动态创建一个包含“not in”值列表的字符串,然后将它们附加到 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;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-25
      • 2022-12-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-01
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      相关资源
      最近更新 更多