Запит SQLite в Android для підрахунку рядків


91

Я намагаюся створити просту форму для входу, де я порівнюю ідентифікатор і пароль для входу, введені на екрані входу, з тими, що зберігаються в базі даних.

Я використовую такий запит:

final String DATABASE_COMPARE =
"select count(*) from users where uname=" + loginname + "and pwd=" + loginpass + ");" ;

Проблема в тому, що я не знаю, як я можу виконати наведений вище запит і зберегти повернутий рахунок.

Ось як виглядає таблиця бази даних (я успішно створив базу даних за допомогою методу execSQl)

private static final String
DATABASE_CREATE =
            "create table users (_id integer autoincrement, "
            + "name text not null, uname primary key text not null, " 
            + "pwd text not null);";//+"phoneno text not null);";

Чи може хтось люб’язно допомогти мені, як я можу цього досягти? Якщо можливо, надайте зразок фрагмента для виконання вищевказаного завдання.

Відповіді:


121

DatabaseUtils.queryNumEntries (з api: 11) є корисною альтернативою, яка заперечує потребу в необробленому SQL (yay!).

SQLiteDatabase db = getReadableDatabase();
DatabaseUtils.queryNumEntries(db, "users",
                "uname=? AND pwd=?", new String[] {loginname,loginpass});

для ОС <11 він отримує помилку NoSuchMethodError, чи є якесь обхідне рішення для підтримки ОС <11?
Хобайб

2
@Khobaib Перевірте відповідь від ghchinoy
Едуардо Герцер

1
@EduardoHerzer Я знайшов спосіб безпосередньо з cursor.getCount ().
Хобайб

1
@Khobaib Це не дуже ефективний спосіб зробити це. Ви завжди повинні віддавати перевагу використанню SELECT COUNT(*)та queryNumEntries()перевиробленню всіх записів та перегляду їх кількості, тобто. cursor.getCount()
DearVolt

114

@scottyab параметризований DatabaseUtils.queryNumEntries (db, table, whereparams) існує в API 11 +, той, де whereparams не існує з API 1 . Відповіддю повинно бути створення курсора з db.rawQuery:

Cursor mCount= db.rawQuery("select count(*) from users where uname='" + loginname + "' and pwd='" + loginpass +"'", null);
mCount.moveToFirst();
int count= mCount.getInt(0);
mCount.close();

Мені також подобається відповідь @ Dre із параметризованим запитом.


1
Для тих, хто цікавиться, параметром mCount.getInt()є columnindex. Дякуємо за допомогу!
T.Woody

62

Використовуйте SQLiteStatement .

напр

 SQLiteStatement s = mDb.compileStatement( "select count(*) from users where uname='" + loginname + "' and pwd='" + loginpass + "'; " );

  long count = s.simpleQueryForLong();

1
Одне, що мені подобається у цій відповіді проти відповіді @ scottyab (що теж дуже добре), - це те, що ви можете вказати пропозицію LIMIT у цьому випадку. Це корисно, коли ви просто хочете дізнатися, чи є в таблиці БУДЬ-ЯКІ рядки (наприклад, виберіть (count (*)> 0) з TABLE LIMIT 1) проти жодних рядків. Я припускаю, що це буде швидше, коли в таблиці не може бути рядків або тонни рядків. Це конкретний випадок, який я мав, коли шукав це ...
stuckj

@Teknogrebo: Це гарна відповідь, хоча я б використовував параметризовану версію. Ви можете використовувати ?s у запиті, а потім використовувати bindString(int, String)і, bindLong(int, long)щоб вставити значення. Дивіться тут .
DearVolt

22

Див. RawQuery (String, String []) та документацію до курсору

Наразі ваш оператор DADABASE_COMPARE недійсний, loginnameі loginpassйого не буде екрановано, між loginnameі не залишається пробілу and, і ви закінчуєте оператор з); замість ; - Якби ви входили як bob з паролем пароля, ця заява закінчувалася б як

select count(*) from users where uname=boband pwd=password);

Крім того, вам, ймовірно, слід використовувати функцію selectionArgs, замість того, щоб об'єднувати ім'я для входу та пароль для входу.

Щоб використовувати selectionArgs, ви зробили б щось на зразок

final String SQL_STATEMENT = "SELECT COUNT(*) FROM users WHERE uname=? AND pwd=?";

private void someMethod() {
    Cursor c = db.rawQuery(SQL_STATEMENT, new String[] { loginname, loginpass });
    ...
}

22

Якщо припустити, що у вас вже встановлено з'єднання Database ( db), я думаю, що найелегантнішим способом є дотримуватися Cursorкласу і робити щось на зразок:

String selection = "uname = ? AND pwd = ?";
String[] selectionArgs = {loginname, loginpass};
String tableName = "YourTable";
Cursor c = db.query(tableName, null, selection, selectionArgs, null, null, null);
int result = c.getCount();
c.close();
return result;

2
Ви повинні принаймні вказати стовпець. Передача null повертає всі стовпці, що не рекомендується запобігати читанню даних із сховища, яке не буде використовуватися. #perfmatters
redochka

Насправді, якщо необхідна інформація - це лише підрахунок, отримання одного стовпця (наприклад, ідентифікатора) було б більш ніж достатньо
Елой Наварро,

12

як отримати стовпець підрахунку

final String DATABASE_COMPARE = "select count(*) from users where uname="+loginname+ "and pwd="+loginpass;

int sometotal = (int) DatabaseUtils.longForQuery(db, DATABASE_COMPARE, null);

Це найкоротша і найточніша альтернатива. Не потрібно обробляти курсори та їх закриття.


Дивовижно - я працюю з Android назавжди і ніколи не знав про цю базу данихUtils - Google повинен краще просувати там утиліти ...
slott

6

Якщо ви використовуєте ContentProvider, ви можете використовувати:

Cursor cursor = getContentResolver().query(CONTENT_URI, new String[] {"count(*)"},
            uname=" + loginname + " and pwd=" + loginpass, null, null);
    cursor.moveToFirst();
    int count = cursor.getInt(0);

5

Інший спосіб - використання:

myCursor.getCount();

на курсорі типу:

Cursor myCursor = db.query(table_Name, new String[] { row_Username }, 
row_Username + " =? AND " + row_Password + " =?",
new String[] { entered_Password, entered_Password }, 
null, null, null);

Якщо ви можете подумати відійти від необробленого запиту.


5

Якщо ви хочете отримати кількість записів, вам доведеться застосувати групу до якогось поля або застосувати наведений нижче запит.

Подібно до

db.rawQuery("select count(field) as count_record from tablename where field =" + condition, null);

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.