Phương thức SQLiteDatabase.query


121

Tôi đang sử dụng phương pháp truy vấn của SQLiteDatabase. Làm cách nào để sử dụng phương pháp truy vấn?

Tôi đã thử điều này:

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

tableColumns - tham số cột được xây dựng như sau.

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

Nếu chúng ta cần lấy tất cả các trường, thì tham số cột sẽ được xây dựng như thế nào. Chúng ta có cần bao gồm tất cả các Tên trường trong mảng Chuỗi không?

Làm cách nào để sử dụng đúng phương pháp truy vấn?


1
Hãy thử một cách tiếp cận đơn giản như thế này
Imran Rana

Tôi biết phương pháp đó. Nhưng tôi đang cố gắng học cách triển khai phương thức truy vấn thay vì rawQuery.
sree_iphonedev

Câu trả lời:


244

tableColumns

  • null cho tất cả các cột như trong SELECT * FROM ...
  • new String[] { "column1", "column2", ... }cho các cột cụ thể như trong SELECT column1, column2 FROM ...- bạn cũng có thể đặt các biểu thức phức tạp ở đây:
    new String[] { "(SELECT max(column1) FROM table1) AS max" }sẽ cung cấp cho bạn một cột có tên maxchứa giá trị tối đa củacolumn1

ở đâu

  • phần bạn đặt sau WHEREmà không có từ khóa đó, ví dụ:"column1 > 5"
  • nên bao gồm ?những thứ động, ví dụ "column1=?"-> xemwhereArgs

whereArgs

  • chỉ định nội dung điền ?vào từng whereClausethứ theo thứ tự chúng xuất hiện

những người khác

  • giống như whereClausecâu lệnh sau từ khóa hoặc nullnếu bạn không sử dụng nó.

Thí dụ

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

tương đương với truy vấn thô sau đây

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

Bằng cách sử dụng phiên bản Where / Bind -Args, bạn sẽ nhận được các giá trị tự động thoát và bạn không phải lo lắng nếu dữ liệu đầu vào có chứa '.

Không an toàn: String whereClause = "column1='" + value + "'";
An toàn:String whereClause = "column1=?";

bởi vì nếu giá trị chứa một 'câu lệnh của bạn hoặc là ngắt và bạn nhận được ngoại lệ hoặc thực hiện những điều không mong muốn, ví dụ: value = "XYZ'; DROP TABLE table1;--"thậm chí có thể làm rớt bảng của bạn vì câu lệnh sẽ trở thành hai câu lệnh và một nhận xét:

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

sử dụng phiên bản args XYZ'; DROP TABLE table1;--sẽ được thoát đến 'XYZ''; DROP TABLE table1;--'và sẽ chỉ được coi là một giá trị. Ngay cả khi 'nó không nhằm mục đích làm điều xấu, vẫn khá phổ biến là mọi người có nó trong tên của họ hoặc sử dụng nó trong văn bản, tên tệp, mật khẩu, v.v. Vì vậy, hãy luôn sử dụng phiên bản args. (Tuy nhiên, có thể xây dựng intvà các nguyên thủy khác trực tiếp vào whereClause)


Giới hạn / bù đắp nằm ở đâu trong ... nhóm này bởi? đang có? đặt bởi?
Lion789

3
@ Lion789 có một số phiên bản có một limittham số, ví dụ: developer.android.com/reference/android/database/sqlite/… cuối cùng tất cả chỉ là ghép văn bản đơn giản để bạn có thể đưa ví dụ "some_column LIMIT 10"vào orderByvà nó vẫn hoạt động
zapl

Có tùy chọn nào ở đây để tham gia 2 bảng không?
Vijay Kumbhoje

2
@VijayKumbhoje bạn có thể đặt ví dụ table1 CROSS JOIN table2như tên bảng. Nhưng có một điểm mà tôi sẽ xem xét rawquery: stackoverflow.com/q/10598137/995891
zapl

3
@VijayKumbhoje bất cứ thứ gì bạn cảm thấy thoải mái hơn / cuối cùng trông sạch sẽ hơn. Các queryphương thức chỉ đơn thuần là thêm một vài từ khóa như SELECTFROMvào các đối số (xem nguồn) sau đó thực hiện rawQueryvới chuỗi truy vấn kết quả. Nếu truy vấn của bạn không phù hợp với các đối số có sẵn của query, chỉ cần tự viết chuỗi truy vấn.
zapl

21

Đây là câu trả lời tổng quát hơn có nghĩa là tham khảo nhanh cho những người xem trong tương lai.

Thí dụ

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

Giải thích từ tài liệu

  • table Chuỗi: Tên bảng để biên dịch truy vấn.
  • columns Chuỗi: Danh sách các cột sẽ trả về. Việc vượt qua null sẽ trả về tất cả các cột, điều này không được khuyến khích để ngăn việc đọc dữ liệu từ bộ nhớ sẽ không được sử dụng.
  • selection Chuỗi: Bộ lọc khai báo những hàng nào sẽ trả về, được định dạng dưới dạng mệnh đề WHERE trong SQL (ngoại trừ bản thân WHERE). Vượt qua null sẽ trả về tất cả các hàng cho bảng đã cho.
  • selectionArgs Chuỗi: Bạn có thể bao gồm? Trong lựa chọn, sẽ được thay thế bằng các giá trị từ selectArgs, để chúng xuất hiện trong lựa chọn. Các giá trị sẽ được ràng buộc dưới dạng Chuỗi.
  • groupBy Chuỗi: Bộ lọc khai báo cách nhóm các hàng, được định dạng dưới dạng mệnh đề GROUP BY trong SQL (ngoại trừ chính GROUP BY). Vượt qua null sẽ khiến các hàng không được nhóm lại.
  • having Chuỗi: Bộ lọc khai báo nhóm hàng nào sẽ bao gồm trong con trỏ, nếu nhóm hàng đang được sử dụng, được định dạng dưới dạng mệnh đề HAVING trong SQL (ngoại trừ chính HAVING). Việc chuyển null sẽ khiến tất cả các nhóm hàng được đưa vào và bắt buộc phải có khi nhóm hàng không được sử dụng.
  • orderBy Chuỗi: Cách sắp xếp thứ tự các hàng, được định dạng như một mệnh đề ORDER BY trong SQL (không bao gồm ORDER BY chính nó). Chuyển null sẽ sử dụng thứ tự sắp xếp mặc định, có thể không có thứ tự.
  • limit Chuỗi: Giới hạn số hàng được trả về bởi truy vấn, được định dạng là mệnh đề LIMIT. Vượt qua null biểu thị không có điều khoản LIMIT.

16

Mệnh đề Where và args làm việc cùng nhau để tạo thành câu lệnh WHERE của truy vấn SQL. Vì vậy, nói rằng bạn muốn thể hiện

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

Sau đó, whereClause và whereArgs của bạn sẽ như sau

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

Nếu bạn muốn chọn tất cả các cột của bảng, tôi tin rằng một chuỗi null được chuyển đến tableColumns là đủ.


không bao gồm ?trong ', 'được thêm tự động nếu cần
zapl

1

nếu truy vấn SQL của bạn giống như thế này

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;

Sau đó, đối với phương thức query (), chúng ta có thể làm như sau: -

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 + "=" + rowID, đây =wheremệnh đề. Để chọn tất cả các giá trị, bạn sẽ phải đặt tên cho tất cả các cột:

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

và đây là một hướng dẫn tốt cho cơ sở dữ liệu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.