Задача, которую мне дали, - написать запрос, чтобы вернуть количество потерянных строк.Я достиг этого, но другая задача состоит в том, чтобы затем не использовать метод rawQuery для достижения того же результата, используя метод запроса.
Проблема заключается в том, что я получаю java.lang.IllegalStateException: Недопустимые таблицы
Таблицы, есть 3:
- родительская таблица, которая имеет столбец _id и столбец имени
- дочерняя таблица, которая имеет столбец _id, столбец имени и дочернюю родительскую ссылкустолбец, представляющий собой целое число, которое ссылается на родительскую таблицу.
- таблица друзей, в которой есть столбец _id, столбец имени и столбец friendtochildlink.
SQL для создания иположить строки в таблицы, в том числе некоторые сироты, как
CREATE TABLE parent(_id INTEGER PRIMARY KEY,parentname TEXT);
CREATE TABLE child(_id INTEGER PRIMARY KEY,childname TEXT, childtoparentlink INTEGER);
CREATE TABLE friend(_id INTEGER PRIMARY KEY,friendname TEXT, friendtochildlink INTEGER);
INSERT INTO parent VALUES(null,'Parent A');
INSERT INTO parent VALUES(null,'Parent B');
INSERT INTO child VALUES(null,'Child A',1);
INSERT INTO child VALUES(null,'Child B',2);
INSERT INTO child VALUES(null,'Child X',10); -- orphan
INSERT INTO friend VALUES(null,'Friend A',1);
INSERT INTO friend VALUES(null,'Friend B',2);
INSERT INTO friend VALUES(null,'Friend X',100); -- orphan
Запрос, который работает и дает правильные значения при использовании rawQuery:
SELECT
(
SELECT count() FROM child
LEFT JOIN parent ON child.childtoparentlink = parent._id
WHERE parent.parentname IS NULL
) AS child_mismatches,
(
SELECT count() FROM friend
LEFT JOIN child ON friend.friendtochildlink = child._id
WHERE child.childname IS NULL
) AS friend_mismatches
- Я получаю по два столбца каждыйсо значением 1 (по желанию).
Мой фактический код: -
public ArrayList<String> checkLinkIntegrity() {
ArrayList<String> return_value = new ArrayList<>();
String suffix = "_mismatches";
String child_result_cl = TB_CHILD + suffix;
String sq_child_mismatches = "(SELECT count() FROM " +
TB_CHILD +
" LEFT JOIN " + TB_PARENT +
" ON " + TB_CHILD + "." + CL_CHILDTOPARENTLINK + " = " +
TB_PARENT + "." + CL_PARENTID +
" WHERE " + TB_PARENT + "." + CL_PARENTNAME + " IS NULL)" +
" AS " + child_result_cl;
String friend_result_cl = TB_FRIEND + suffix;
String sq_friend_mismatches = "(SELECT count() FROM " +
TB_FRIEND +
" LEFT JOIN " + TB_CHILD +
" ON " + TB_FRIEND + "." + CL_FRIENDTOCHILDLINK + " = " +
TB_CHILD + "." + CL_CHILD_ID +
" WHERE " + TB_CHILD + "." + CL_CHILDNAME + " IS NULL)" +
" AS " + friend_result_cl;
String full_query = "SELECT " + sq_child_mismatches + "," + sq_friend_mismatches;
SQLiteDatabase db = this.getWritableDatabase();
Cursor csr;
Log.d("RAWQUERYSQL",full_query);
csr = db.rawQuery(full_query,null);
return_value.addAll(dumpCursorToStringArrayList(csr,"RAWQUERY"));
// Fails invalid table
csr = db.query(null,new String[]{sq_child_mismatches,sq_friend_mismatches},null,null,null,null,null);
return_value.addAll(dumpCursorToStringArrayList(csr,"SECONDTRY"));
csr.close();
return return_value;
}
, а метод dumpCursortoStringArrayList: -
private ArrayList<String> dumpCursorToStringArrayList(Cursor csr, String tablename) {
ArrayList<String> rv = new ArrayList<>();
int original_position = csr.getPosition();
csr.moveToPosition(-1);
rv.add("Table: " + tablename);
while (csr.moveToNext()) {
rv.add("\tRow # " + String.valueOf(csr.getPosition() + 1));
for (String column: csr.getColumnNames()) {
rv.add("\t\tColumn: " + column + "\tvalue is: \t" + csr.getString(csr.getColumnIndex(column)));
}
}
csr.moveToPosition(original_position);
return rv;
}
Я получаю ту же ошибку, еслиЯ пытаюсь "" вместо нуля, например
Если я использую только rawQuery, я получаю
04-22 07:07:33.914 6271-6271/s.q001 I/RESULTS: Table: RAWQUERY
04-22 07:07:33.914 6271-6271/s.q001 I/RESULTS: Row # 1
04-22 07:07:33.914 6271-6271/s.q001 I/RESULTS: Column: child_mismatches value is: 1
04-22 07:07:33.914 6271-6271/s.q001 I/RESULTS: Column: friend_mismatches value is: 1
Это от использования
ArrayList<String> results = DBOpenHelper.checkLinkIntegrity();
for (String s : results) {
Log.i("RESULTS",s);
}
Как я могу выполнить запросс методом запроса вместо метода rawQuery, чтобы получить лучшие оценки?