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.