Autore Topic: Eseguire query con join e nested query  (Letto 673 volte)

Offline omix

  • Nuovo arrivato
  • *
  • Post: 23
  • Respect: 0
    • Mostra profilo
Eseguire query con join e nested query
« il: 30 Giugno 2011, 12:51:19 CEST »
0
Buongiorno a tutti,

ho creato un nuovo ContentProvider per gestire un database con una decina di tabelle. Finora ho avuto bisogno solo di fare query semplici, attraverso managedQuery come:
Codice (Java): [Seleziona]
                Cursor cursor = managedQuery(
                                MyInfos.Table2.CONTENT_URI,
                                new String[] {MyInfos.Table2.FIELD2, MyInfos.Table2.FIELD3},
                                null,null,null);

corrispondente a:
Codice (SQL): [Seleziona]
SELECT field2, field3 FROM Table2
Ora però avrò bisogno di fare query più complesse, del tipo:
Codice (SQL): [Seleziona]
SELECT Table1.field2, Table2.field2, Table3.field3 FROM Table1 JOIN Table2 ON Table1.field1=Table2.Field2
e
Codice (SQL): [Seleziona]
SELECT field2  FROM Table2 WHERE field3= (SELECT MAX(field3 FROM Table2 WHERE field3<='10')
Spero possiate aiutarmi, purtroppo in giro ho trovato solo esempi abbastanza basilari...

Grazie in anticipo


Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Eseguire query con join e nested query
« Risposta #1 il: 30 Giugno 2011, 13:03:22 CEST »
0

Spero possiate aiutarmi, purtroppo in giro ho trovato solo esempi abbastanza basilari...


Il trucchetto sta nell'usare invece che il nome della tabella direttamente il join:

Codice (Java): [Seleziona]
        private static final String EVENTS_CATEGORY_JOIN = "events  INNER JOIN categories ON (events.cat_id = categories._id)";
e poi

Codice (Java): [Seleziona]
query = SQLiteQueryBuilder.buildQueryString(false, EVENTS_CATEGORY_JOIN, projection, null, null, null, null, null);
dovresti escogitare una cosa del genere anche per la  subquery :)

Offline omix

  • Nuovo arrivato
  • *
  • Post: 23
  • Respect: 0
    • Mostra profilo
Re:Eseguire query con join e nested query
« Risposta #2 il: 30 Giugno 2011, 16:52:55 CEST »
0
Ciao Ricky,

ti ringrazio della risposta, ma mi manca un passaggio (sono nuovo di Android). Come faccio a passare la stringa che otterrei con SQLiteQueryBuilder al ContentProvider, il quale si occupa di gestire l'apertura del database?
Per come ho implementato il ContentProvider ora, la select legge l'URI passato alla select, e facendo il parser match sceglie quali tabelle impostare al querybuilder e infine apre il database ed esegue la query (più o meno come in tutti gli esempi). Mi viene il dubbio che la tua soluzione funzioni su un database "semplice" e non implementato attraverso un nuovo ContentProvider (che mi occorre perchè il database dovrà essere condiviso tra varie applicazioni).
Non son sicuro di aver capito bene il tuo suggerimento o la gestione del database da parte di Android (finora ho sempre sviluppato applicazioni per sistemi desktop)... se mi puoi dare qualche dritta in più mi renderesti felice :-)

Offline omix

  • Nuovo arrivato
  • *
  • Post: 23
  • Respect: 0
    • Mostra profilo
Re:Eseguire query con join e nested query
« Risposta #3 il: 01 Luglio 2011, 12:04:36 CEST »
0
Ok, sono riuscito a creare le stringhe per le query con SQLiteQueryBuilder.buildQueryString e ho visto che con buildUnionQuery potrei comporle per ottenere la query annidata.
Ora resta il problema di come eseguire queste query da una activity, e quindi non all'interno dell'implementazione del ContentProvider... un aiutino?! :P
In se chiamo getContentResolver().query() non posso passare nè il query builder, nel la stringa che ho creato... e negli argomenti non c'è nulla per settare le tabelle. L'unica, sporchissima, soluzione che ho pensato è di passare a ContentProvider.query() l'uri dell'authority, e nello switch-case relativo a tale uri settare con setTables TUTTE le tabelle (così riuscirei a fare i join, ma non le query annidate).
Ho già perso complessivamente 2 giorni :-(

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Eseguire query con join e nested query
« Risposta #4 il: 01 Luglio 2011, 12:10:08 CEST »
0
Il query builder lo devi usare all'interno del content provider! Dall'esterno infatti i Content Provider non si accedono tramite query sql ma solo ed esclusivamente tramite il content uri.

La mia implementazione del metodo query è la seguente:

Codice (Java): [Seleziona]
        public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {

                Cursor c = null;

                int match = URI_MATCHER.match(uri);
                String query;

                switch (match) {
                case EVENTS:
                        query = SQLiteQueryBuilder.buildQueryString(false,
                                        EVENTS_CATEGORY_JOIN, projection, null, null, null, null, null);
                        break;
                case EVENT_ID:
                        query = SQLiteQueryBuilder.buildQueryString(false,
                                        EVENTS_CATEGORY_JOIN, projection, String.format(
                                                        "events._id=%s", uri.getPathSegments().get(1)),
                                        null, null, null, null);
                        break;
                default:
                        throw new IllegalArgumentException("Unknown URL " + uri);
                }

                c = getReadableDatabase().rawQuery(query, null);
                c.setNotificationUri(getContext().getContentResolver(), uri);
                return c;
        }

2)Devi definirti un

Offline omix

  • Nuovo arrivato
  • *
  • Post: 23
  • Respect: 0
    • Mostra profilo
Re:Eseguire query con join e nested query
« Risposta #5 il: 01 Luglio 2011, 12:20:18 CEST »
0
Grazie Ricky,

avevo fatto questo per ogni tabella, ma speravo di non doverlo fare anche per gestire eventi per query più complesse. Non so dire se sia una soluzione elegante, ma sicuramente costringe a scrivere un sacco di codice in + :-(