2011-01-16 27 views
21

Tôi đang cố gắng chạy NOT IN chọn nơi danh sách NOT IN là động. Một cái gì đó nhưAndroid Sqlite IN, NOT IN syntax

SELECT id, type FROM CONTACTS where type NOT IN ('connect','answer') 

Trong mã nỗ lực vô ích của tôi là:

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 

Đưa tôi về vấn đề này là ? thay đối xử với danh sách dấu phẩy của tôi như là đối số duy nhất. Tôi đã tìm thấy một giải pháp nhưng nó là khá xấu xí vì vậy tôi sẽ không đăng nó ở đây cho đến khi ai đó đi về phía trước với một cái gì đó thanh lịch hơn

Trả lời

21

Bạn không thể đặt chỉ một '?' thay vì danh sách các giá trị. Như vậy, có rất ít để đạt được từ cố gắng để parametrize danh sách. Người ta có thể, tất nhiên, tạo ra 2,4,16-giá trị chuẩn bị báo cáo ..." type NOT IN (?,?)", new String[]{ "connect","answer" },... nhưng ngay cả trên một máy chủ với RDBMS từ xa nó có giá trị đáng ngờ. Thay vào đó, hãy làm

db.query(TABLE, new String[] { "id", ""}, " type NOT IN ('connect','answer')", 
    null, null, null, null); 
nếu danh sách là động, bạn sẽ phải thoát khỏi chuỗi và đặt chúng vào danh sách được trích dẫn duy nhất.

+0

Nếu chuỗi trong câu hỏi là từ một danh sách mà bạn cung cấp chứ không phải là một danh sách người dùng cung cấp, sau đó bạn có thể biết rằng chúng an toàn và thậm chí không cần phải thoát khỏi chúng (trừ khi chúng có chứa một '). –

+0

Đó là khá nhiều giải pháp tôi đã kết thúc với. Đã hy vọng cho một mẹo nhỏ nhưng tôi đoán không có gì. Vẫn muốn chờ một chút để xem có đề xuất thay thế nào hay không – Bostone

+0

Thông tin quen thuộc hơn với Tiêu chí Hibernate có IN được hỗ trợ tốt, tuy nhiên không tìm thấy bất kỳ tương đương nào trong SDK Android. –

1

Bạn có thể có nó tự động sử dụng "không" nếu bạn tự động tạo ra một chuỗi có chứa danh sách "không" giá trị và sau đó gắn nó vào phần cuối của chuỗi sql của bạn như thế nào trong những điều sau đây:

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; 
} 
3

Bạn có thể sử dụng String.format để thiết lập động args.

ví dụ:

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);