SQLiteDatabase.query


121

Używam metody zapytania SQLiteDatabase. Jak używać metody zapytania?

Próbowałem tego:

Cursor cursor = sqLiteDatabase.query(
    tableName, tableColumns, whereClause, whereArgs, groupBy, having, orderBy);

TableColumns - Parametr kolumny jest zbudowany w następujący sposób.

String[] columns = new String[]{KEY_ID, KEY_CONTENT};

Jeśli potrzebujemy pobrać wszystkie pola, w jaki sposób należy skonstruować parametr kolumny. Czy musimy uwzględnić wszystkie nazwy pól w tablicy ciągów?

Jak prawidłowo używać metody zapytania?


1
Spróbuj podejście prosty jak ten
— Imran Rana

Znam tę metodę. Ale próbuję się nauczyć, jak zaimplementować metodę zapytania zamiast rawQuery.
— sree_iphonedev

Odpowiedzi:


244

tableColumns

  • null dla wszystkich kolumn jak w SELECT * FROM ...
  • new String[] { "column1", "column2", ... }dla określonych kolumn, jak w SELECT column1, column2 FROM ...- możesz tu również umieścić złożone wyrażenia:
    new String[] { "(SELECT max(column1) FROM table1) AS max" }dałoby ci kolumnę o nazwie maxzawierającą maksymalną wartośćcolumn1

whereClause

  • część, którą wstawiłeś WHEREbez tego słowa kluczowego, np"column1 > 5"
  • powinien uwzględniać ?rzeczy, które są dynamiczne, np. "column1=?"-> zobaczwhereArgs

whereArgs

  • określić treść, która wypełnia każdy ?w whereClausew kolejności ich występowania

inni

  • podobnie jak whereClauseinstrukcja po słowie kluczowym lub nulljeśli jej nie używasz.

Przykład

String[] tableColumns = new String[] {
    "column1",
    "(SELECT max(column1) FROM table2) AS max"
};
String whereClause = "column1 = ? OR column1 = ?";
String[] whereArgs = new String[] {
    "value1",
    "value2"
};
String orderBy = "column1";
Cursor c = sqLiteDatabase.query("table1", tableColumns, whereClause, whereArgs,
        null, null, orderBy);

// since we have a named column we can do
int idx = c.getColumnIndex("max");

jest odpowiednikiem następującego nieprzetworzonego zapytania

String queryString =
    "SELECT column1, (SELECT max(column1) FROM table1) AS max FROM table1 " +
    "WHERE column1 = ? OR column1 = ? ORDER BY column1";
sqLiteDatabase.rawQuery(queryString, whereArgs);

Używając wersji Where / Bind -Args, otrzymujesz automatycznie wartości ucieczki i nie musisz się martwić, jeśli dane wejściowe zawierają '.

Niebezpieczny: String whereClause = "column1='" + value + "'";
bezpieczny:String whereClause = "column1=?";

ponieważ jeśli wartość zawiera 'twoje wyrażenie, albo zepsuje się i otrzymasz wyjątki, albo zrobisz niezamierzone rzeczy, na przykład value = "XYZ'; DROP TABLE table1;--"może nawet upuścić twoją tabelę, ponieważ instrukcja stanie się dwoma instrukcjami i komentarzem:

SELECT * FROM table1 where column1='XYZ'; DROP TABLE table1;--'

użycie wersji args XYZ'; DROP TABLE table1;--zostałoby zmienione 'XYZ''; DROP TABLE table1;--'i traktowane jako wartość. Nawet jeśli 'nie jest przeznaczony do robienia złych rzeczy, nadal jest dość powszechne, że ludzie mają go w swoich nazwach lub używają go w tekstach, nazwach plików, hasłach itp. Dlatego zawsze używaj wersji args. (Można intbezpośrednio budować i inne prymitywy whereClause)


Gdzie mieści się limit / offset w tej ... grupie według? mający? Zamów przez?
— Lion789

3
@ Lion789 istnieje kilka wersji, które mają limitparametr, np developer.android.com/reference/android/database/sqlite/... to wszystko to tylko prosty konkatenacji tekstowy w końcu, dzięki czemu można umieścić np "some_column LIMIT 10"na orderByi nadal praca
— zapl

Jest jakaś opcja dołączenia do 2 stolików?
— Vijay Kumbhoje

2
@VijayKumbhoje powinieneś być w stanie umieścić np. table1 CROSS JOIN table2Jako nazwę tabeli. Ale jest moment, w którym spojrzałbym na rawquery: stackoverflow.com/q/10598137/995891
— zapl

3
@VijayKumbhoje wszystko, z czym czujesz się bardziej komfortowo / wygląda na czystsze w końcu. Te querymetody są tylko dodanie kilku słów kluczowych, jak SELECTi FROMna argumenty (patrz źródła) , a następnie zrobić rawQueryz powstałego łańcucha zapytania. Jeśli zapytanie nie pasuje dobrze do dostępnych argumentów query, po prostu napisz ciąg zapytania samodzielnie.
— zapl

21

Jest to bardziej ogólna odpowiedź, która ma być szybkim źródłem informacji dla przyszłych widzów.

Przykład

SQLiteDatabase db = helper.getReadableDatabase();

String table = "table2";
String[] columns = {"column1", "column3"};
String selection = "column3 =?";
String[] selectionArgs = {"apple"};
String groupBy = null;
String having = null;
String orderBy = "column3 DESC";
String limit = "10";

Cursor cursor = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);

Wyjaśnienie z dokumentacji

  • table Ciąg: nazwa tabeli, względem której zostanie skompilowane zapytanie.
  • columns Ciąg: lista kolumn do zwrócenia. Przekazanie wartości null zwróci wszystkie kolumny, co jest odradzane, aby zapobiec odczytaniu danych z pamięci, które nie będą używane.
  • selection Ciąg: filtr deklarujący wiersze do zwrócenia, sformatowany jako klauzula SQL WHERE (z wyłączeniem samej WHERE). Podanie wartości null zwróci wszystkie wiersze z podanej tabeli.
  • selectionArgs Ciąg: możesz uwzględnić w zaznaczeniu? S, które zostaną zastąpione wartościami z selectionArgs, aby pojawiły się w zaznaczeniu. Wartości zostaną powiązane jako ciągi.
  • groupBy Ciąg: filtr deklarujący sposób grupowania wierszy, sformatowany jako klauzula SQL GROUP BY (z wyłączeniem samego GROUP BY). Przekazanie wartości null spowoduje, że wiersze nie będą grupowane.
  • having Łańcuch: filtr deklaruje, które grupy wierszy mają zostać uwzględnione w kursorze, jeśli używane jest grupowanie wierszy, sformatowane jako klauzula SQL HAVING (z wyłączeniem samego HAVING). Przekazanie wartości null spowoduje uwzględnienie wszystkich grup wierszy i jest wymagane, gdy grupowanie wierszy nie jest używane.
  • orderBy Ciąg: jak porządkować wiersze sformatowane jako klauzula SQL ORDER BY (z wyłączeniem samego ORDER BY). Podanie wartości null spowoduje użycie domyślnej kolejności sortowania, która może być nieuporządkowana.
  • limit Ciąg: ogranicza liczbę wierszy zwracanych przez zapytanie, sformatowaną jako klauzula LIMIT. Przekazanie null oznacza brak klauzuli LIMIT.

16

Klauzula Where i argumenty współpracują ze sobą, tworząc instrukcję WHERE zapytania SQL. Więc powiedz, że chcesz wyrazić

WHERE Column1 = 'value1' AND Column2 = 'value2'

Wtedy twoje whereClause i whereArgs będą następujące

String whereClause = "Column1 =? AND Column2 =?";
String[] whereArgs = new String[]{"value1", "value2"};

Jeśli chcesz zaznaczyć wszystkie kolumny tabeli, uważam, że łańcuch o wartości null przekazany do tableColumns wystarczy.


nie ująć ?w 'The 'dodaje automatycznie w razie potrzeby
— zapl

1

jeśli twoje zapytanie SQL jest takie

SELECT col-1, col-2 FROM tableName WHERE col-1=apple,col-2=mango
GROUPBY col-3 HAVING Count(col-4) > 5  ORDERBY col-2 DESC LIMIT 15;

Następnie dla metody query () możemy zrobić tak: -

String table = "tableName";
String[] columns = {"col-1", "col-2"};
String selection = "col-1 =? AND col-2=?";       
String[] selectionArgs = {"apple","mango"};
String groupBy =col-3;
String having =" COUNT(col-4) > 5";
String orderBy = "col-2 DESC";
String limit = "15";

query(tableName, columns, selection, selectionArgs, groupBy, having, orderBy, limit);

0
db.query(
        TABLE_NAME,
        new String[] { TABLE_ROW_ID, TABLE_ROW_ONE, TABLE_ROW_TWO },
        TABLE_ROW_ID + "=" + rowID,
        null, null, null, null, null
);

TABLE_ROW_ID + "=" + rowIDTu =jest whereklauzula. Aby wybrać wszystkie wartości, musisz podać nazwy wszystkich kolumn:

or you can use a raw query like this 
db.rawQuery("SELECT * FROM permissions_table WHERE name = 'Comics' ", null);

a tutaj jest dobry poradnik dotyczący bazy danych.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.