Страница 1 из 11

Урок 36. SQLite. Подробнее про метод query. Условие, сортировка, группировка

Добавлено: 24 ноя 2011, 03:00
damager82
В этом уроке:

- подробно разбираем метод чтения данных query
- используем сортировку, группировку, условия, having

Click here to read this article!

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 03 июн 2012, 16:31
ermek6
Вопрос по организации кода.
Зачем получать курсор в каждом кейсе. Ведь переменные то мы и так установили все в null. Можно же один раз курсор получить после switch. Или же для этого были другие причины???

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 04 июн 2012, 10:51
damager82
ermek6 писал(а):Зачем получать курсор в каждом кейсе.
Только для большей наглядности. Чтоб читатель четко видел какие параметры в методе используются для каждого случая.

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 11 авг 2012, 17:56
Quqush
Здравствуйте.
Огромное спасибо за уроки.

Объясните, пожалуйста, эту конструкцию:
for (String cn : c.getColumnNames())

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 11 авг 2012, 20:44
Quqush
Еще вопрос.
Есть такой код:
btnAll = (Button) findViewById(R.id.btnAll);
btnAll.setOnClickListener(this);

я его пишу так:
((Button) findViewById(R.id.btnAll)).setOnClickListener(this);

Когда мы эмулируем нажатие кнопки то первый вариант отлично работает а второй нет, выбрасывается исключение: java.lang.NullPointerException
Но при клике второй вариант тоже отлично работает.
Кто сможет объяснить почему так?

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 11 авг 2012, 22:14
math64
1. for (String cn : c.getColumnNames()) - это аналог foreach в C#. В java решили не вводить новое ключевое слово. Можно перебирать содержимое коллеции или массива.
2. ((Button) findViewById(R.id.btnAll)).setOnClickListener(this); можно упростить до findViewById(R.id.btnAll).setOnClickListener(this); - клик можно ставить на любой View, а не только на кнопки.
java.lang.NullPointerException может появиться в первоначальном варианте, если будет найдена не кнопка, в упрощёном - если ничего не найдено.

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 12 авг 2012, 10:52
Quqush
math64 писал(а):это аналог foreach в C#
Большое спасибо. :!:

Тем не менее 2 вопрос остается открытым.

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 12 авг 2012, 18:40
math64
Т.е. ты хочешь упростить

Код: Выделить всё

btnAll = (Button) findViewById(R.id.btnAll);
btnAll.setOnClickListener(this);
...
onClick(btnAll);
из примера?
упрощается так:

Код: Выделить всё

View btnAll = findViewById(R.id.btnAll);
btnAll.setOnClickListener(this);
...
onClick(btnAll);
Объявление поля Button btnAll; из класса удаляется, как и остальных кнопок (для которых даже локальных переменных не нужно выделять) - эти поля нигде не используются.
Однако, если к кнопке нужно обращение из других методов, лучше найти её и запомнить в поле класса в метода onCreate - чтобы больше не искать.

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 13 авг 2012, 10:27
rezak90
java.lang.NullPointerException выскакивает из-за того что операция выполняется справа на лево, вот переменной сначала нету а ты уже вешаешь обработчик, вот оно и нулл выкидывает... если я не ошибаюсь, а то с утра могу и натупить =)

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 13 авг 2012, 10:53
math64
rezak - нет, из-за того что убрали инициализацию поля класса btnAll, а затем используют неинициализируемую в onClick(btnAll). Поле класса нужно убрать, заменить на локальную переменную - тогда компилятор выдаст предупреждение. Поле класса по умолчанию иницализируется в null, а локальная переменная должна инициализироваться программистом.

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 14 авг 2012, 14:58
Quqush
math64 писал(а):rezak - нет, из-за того что убрали инициализацию поля класса btnAll, а затем используют неинициализируемую в onClick(btnAll). Поле класса нужно убрать, заменить на локальную переменную - тогда компилятор выдаст предупреждение. Поле класса по умолчанию иницализируется в null, а локальная переменная должна инициализироваться программистом.
Вот спасибо! Теперь ясно.

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 20 авг 2012, 13:18
daiz123
do {
str = "";
for (String cn : c.getColumnNames()) {
str = str.concat(cn + " = "
+ c.getString(c.getColumnIndex(cn)) + "; ");
}
Log.d(LOG_TAG, str);

} while (c.moveToNext());
Не могли бы вы подробней описать этот код.
for (String cn : c.getColumnNames()) как работает этот цикл? что означает двоеточие тут?
str.concat что делает эта функция?

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 20 авг 2012, 14:05
math64
Я уже обяснял выше в этой теме: for( v : collection) - это соответвует foreach в C#. ; двоеточие соответствует in. Перебирается содержимое коллекции.
concat() - конкатенация, вместо неё можно использовать + (точнее, все вызовы + для строк заменяются на вызов concat() ).

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 20 авг 2012, 14:29
rezak90
видно по форуму просто не все знакомы не то что с явой а и с шарпом =) ... так что трудно конечно им и возникают такие вот вопросы.

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 21 авг 2012, 13:24
zavbak
Добрый день. Подскажите как можно в качестве сравниваемого значение передать массив например region = {"Америка", "Азия"}. Именно список.

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 21 авг 2012, 13:31
rezak90
zavbak писал(а):Добрый день. Подскажите как можно в качестве сравниваемого значение передать массив например region = {"Америка", "Азия"}. Именно список.
куда передать? я так понял хотите сравнить значения в массиве со значениями в бд?

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 21 авг 2012, 13:49
math64
zavbak писал(а):Добрый день. Подскажите как можно в качестве сравниваемого значение передать массив например region = {"Америка", "Азия"}. Именно список.
WHERE region IN ( 'Америка', 'Азия')
или создать таблицу Continents - тогда
WHERE region = Continents.name

http://www.sqlite.org/lang_expr.html

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 22 авг 2012, 01:13
zavbak
math64 писал(а):
zavbak писал(а):Добрый день. Подскажите как можно в качестве сравниваемого значение передать массив например region = {"Америка", "Азия"}. Именно список.
WHERE region IN ( 'Америка', 'Азия')
или создать таблицу Continents - тогда
WHERE region = Continents.name

http://www.sqlite.org/lang_expr.html


А массив в качестве параметра передать нельзя?

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 22 авг 2012, 07:42
math64
zavbak писал(а):А массив в качестве параметра передать нельзя?
Нет, конечно. Параметр заменяет число или строку в SQL запросе. Если передадите массив, вызовется, полягаю, метод toString(), т.е. параметр будет заменён на хеш-код массива. А в SQL в Вашем случае нужно применть IN или JOIN со вспомогательной таблицей, которой будут записи 'Америка' и 'Азия':
Вот полные SQL:

Код: Выделить всё

SELECT field1, field2, region FROM table1 WHERE region IN ('Америка', 'Азия')
SELECT t.field1, t.field2, t.region FROM table1 AS t JOIN continents AS c ON t.region = c.name

Re: Урок 36. SQLite. Подробнее про метод query. Условие, сор

Добавлено: 22 авг 2012, 08:54
KamiSempai
Второй вариант будет хорошь если записи уже имеются в базе. А если даже таблици такой нет или есть но нужны только те которые выбрал пользователь?
А первый вариант так и просит сделать ему SQL инъекцию :)

Я вот подумал, может такой вариант сойдет?

Код: Выделить всё

String paramString ="?";
for(i = 2; i < paramArray.size() - 1; i++)
  paramString = paramString + ",?";
String sqlString ="SELECT * FROM table WHERE region IN (" + paramString + ")";
Cursor cursor = db.rawQuery (sqlString, paramArray)
Работоспособность не проверял, вроде должно работать.