2011-01-16 15 views
21

Estoy tratando de ejecutar NOT IN seleccionar donde NOT IN la lista es dinámica. Algo así comoAndroid Sqlite IN, NO EN Sintaxis

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

En el código de mis inútiles intentos fueron:

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 

Mi opinión sobre esto es que ? sustitución trata a mi lista coma como único argumento. Encontré una solución, pero es bastante fea, así que no la publicaré aquí hasta que alguien presente algo más elegante

Respuesta

21

No se puede colocar solo una '?' en lugar de una lista de valores Como tal, hay poco que ganar tratando de parametrizar listas. Uno puede, por supuesto, crear declaraciones preparadas de 2,4,16-valores ..." type NOT IN (?,?)", new String[]{ "connect","answer" },... pero incluso en un servidor con RDBMS remoto tiene un valor cuestionable. En su lugar, haga

db.query(TABLE, new String[] { "id", ""}, " type NOT IN ('connect','answer')", 
    null, null, null, null); 
si la lista es dinámica, tendrá que escaparse de las cadenas y ponerlas en una sola lista citada.

+0

Si las cadenas en cuestión son de una lista que usted proporciona en lugar de una lista que proporcione el usuario, entonces usted puede saber que están a salvo y ni siquiera tienen que escapar de ellos (a menos que contengan un '). –

+0

Esa es prácticamente la solución con la que terminé. Esperaba un pequeño truco, pero supongo que no hay ninguno. Todavía quiero esperar un poco para ver si habrá alguna sugerencia alternativa. – Bostone

+0

Más familiarizado con los criterios de Hibernate cuyo IN es bien compatible, sin embargo no se encuentra ningún equivalente en Android SDK. –

1

se puede tener de forma dinámica el uso "no" si dinámicamente crear una cadena que contiene la lista de "no en" los valores y luego añadirse al final de la cadena SQL como en el siguiente:

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

Puede usar String.format para establecer dinámicamente los argumentos.

por ejemplo:

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