2012-04-10 26 views
7

Tôi đang cố truy vấn tất cả các cột trong một bảng thành một dạng xem văn bản dài và/hoặc chuỗi. Tôi biết điều này có thể không đúng cách để làm nhưng tôi phải làm điều này. Đúng tôi nếu tôi sai, tôi đã có ấn tượng rằng di chuyển tiếp theo sẽ nhận được cột tiếp theo trong dòng:android cursor.moveToNext()?

Cursor c = db.get(); 
if(c.moveToFirst){ 
do{ 
string = c.getString(0); 
}while(c.moveToNext); 

Tôi nghĩ rằng điều này sẽ được cột đầu tiên và hiển thị tất cả nội dung của nó thay vì tôi nhận được cột đầu tiên và hàng đầu tiên. Tôi đang làm gì sai? Có cách nào tốt hơn hoặc thực tế hơn để có được thông tin này mà không cần sử dụng ListView?

Trả lời

9

Để rõ ràng, một ví dụ hoàn chỉnh sẽ như sau mà tôi tin tưởng là quan tâm. Như các bình luận mã chỉ ra chúng ta chủ yếu lặp qua các hàng cơ sở dữ liệu và sau đó các cột để tạo thành một bảng dữ liệu theo cơ sở dữ liệu.

Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, 
      null); 

    //if the cursor isnt null we will essentially iterate over rows and then columns 
    //to form a table of data as per database. 
    if (cursor != null) { 

     //more to the first row 
     cursor.moveToFirst(); 

     //iterate over rows 
     for (int i = 0; i < cursor.getCount(); i++) { 

      //iterate over the columns 
      for(int j = 0; j < cursor.getColumnNames().length; j++){ 

       //append the column value to the string builder and delimit by a pipe symbol 
       stringBuilder.append(cursor.getString(j) + "|"); 
      } 
      //add a new line carriage return 
      stringBuilder.append("\n"); 

      //move to the next row 
      cursor.moveToNext(); 
     } 
     //close the cursor 
     cursor.close(); 
    } 
1

moveToNext di chuyển con trỏ đến hàng tiếp theo. và c.getString (0) sẽ luôn cung cấp cho bạn cột đầu tiên nếu có. Tôi nghĩ bạn nên làm điều gì đó tương tự như sau trong vòng lặp của bạn

int index = c.getColumnIndex("Column_Name"); 
string = c.getString(index); 
1

cursor.moveToFirst() di chuyển con trỏ đến dòng đầu tiên. Nếu bạn biết rằng bạn có 6 cột và bạn muốn một chuỗi chứa tất cả các cột, hãy thử các bước sau.

c.moveToFirst(); 
StringBuilder stringBuilder = new StringBuilder(); 
for(int i = 0; i < 6; i++){ 
    stringBuilder.append(c.getString(i)); 
} 

// to return the string, you would do stringBuilder.toString(); 
+1

Và nếu bạn không biết số lượng cột, chỉ cần sử dụng 'c.getColumnCount()' trong vòng lặp 'for'. – Squonk

0

tôi mã hóa vòng của tôi trong cusror như thế này:

cursor.moveToFirst(); 
    while(!cursor.isAfterLast()) { 

      cursor.getString(cursor.getColumnIndex("column_name")); 

     cursor.moveToNext(); 
    } 

Đó luôn luôn hoạt động. Điều này sẽ lấy giá trị của cột "column_name" của tất cả các hàng. Sai lầm của bạn là bạn lặp lại các hàng chứ không phải các cột. Để lặp qua các cột:

cursor.moveToFirst();  
    for(int i = 0; i < cursor.getColumnNames().length; i++){ 
     cursor.getString(i); 
    } 

Điều đó sẽ lặp trên các cột của hàng đầu tiên và lấy mỗi giá trị cột.

30

Việc sử dụng đơn giản là:

Cursor cursor = db.query(...); 
while (cursor.moveToNext()) { 
    ... 
} 

moveToFirst được sử dụng khi bạn cần để bắt đầu lặp lại từ đầu sau khi bạn đã đạt đến một số vị trí.

Tránh sử dụng cursor.getCount() trừ khi được yêu cầu. Và không bao giờ sử dụng vòng lặp trên getCount().

getCount đắt tiền - nó lặp qua nhiều bản ghi để đếm chúng. Nó không trả về một biến được lưu trữ. Có thể có một số bộ nhớ đệm trên một cuộc gọi thứ hai, nhưng cuộc gọi đầu tiên không biết câu trả lời cho đến khi nó được tính.

Nếu truy vấn của bạn phù hợp với 1000 hàng, con trỏ thực sự chỉ có hàng đầu tiên. Mỗi tìm kiếm moveToNext và tìm thấy kết quả phù hợp tiếp theo. getCount phải tìm tất cả 1000. Tại sao lặp lại tất cả nếu bạn chỉ cần 10? Tại sao lặp lại hai lần?

Ngoài ra, nếu truy vấn của bạn không sử dụng chỉ mục, getCount thậm chí có thể chậm hơn - getCount có thể vượt quá 10000 bản ghi mặc dù truy vấn chỉ khớp với 100. Tại sao lặp lại 20000 thay vì 10000?

+1

Như của Android 4.2, 'moveToNext()' được thực hiện bởi 'moveToPosition()' mà [chính nó cũng gọi '.getCount()'] (http: // androidxref.com/4.2.2_r1/xref/framework/base/core/java/android/database/AbstractCursor.java # moveToPosition). Chắc chắn đây chỉ là chi tiết triển khai mà không nên dựa vào. – kennytm

+1

@KennyTM là đúng. Trong thực tế, đây là trường hợp ngay cả trước khi Android 4.2 (xem http://bit.ly/1s8KClM). Hơn nữa, bên cạnh 'moveToNext()' khá nhiều tất cả các hoạt động con trỏ cơ bản khác (ví dụ: 'moveToFirst()', 'isBeforeFirst()' và 'isFirst()') liên quan đến (các) cuộc gọi đến 'getCount()'. Vì vậy, ngay cả khi 'getCount()' là tốn kém nó là không thể tránh khỏi. Hơn nữa, việc thực hiện 'getCount()' lưu trữ giá trị trả về, vì vậy ít nhất các cuộc gọi tiếp theo sẽ rẻ hơn (xem http://bit.ly/1uL4ZEp). – Matthias

Các vấn đề liên quan