Как использовать подготовленный оператор в Spatialite Android?
-
21-12-2019 - |
Вопрос
я смотрю на руководство для Spatialite-Android, и я заметил следующие примеры кода:
String query = "SELECT AsText(Transform(MakePoint(" + TEST_LON + ", " + TEST_LAT + ", 4326), 32632));";
sb.append("Execute query: ").append(query).append("\n");
try {
Stmt stmt = db.prepare(query);
if (stmt.step()) {
String pointStr = stmt.column_string(0);
sb.append("\t").append(TEST_LON + "/" + TEST_LAT + "/EPSG:4326").append(" = ")//
.append(pointStr + "/EPSG:32632").append("...\n");
}
stmt.close();
} catch (Exception e) {
e.printStackTrace();
sb.append(ERROR).append(e.getLocalizedMessage()).append("\n");
}
В частности, я заметил, что плохая практика заключается в простом объединении SQL-запросов вместо более подходящего метода, например, используемого библиотекой Android SQLite.Есть ли способ заставить Spatialite использовать настоящие подготовленные операторы?
Для ясности: я ищу что-то вроде этого, используя стандартную базу данных SQLite в Android:
String query="SELECT * FROM table WHERE _id=?";
Cursor data=db.rawQuery(query,new String[]{id});
Решение
Есть несколько хитростей.Все они используют вызов exec(), который для этой версии имеет 3 аргумента.Заявление от исходный код является:
public void exec(String sql, jsqlite.Callback cb, String args[])
jsqlite.Callback — это интерфейс, которых может быть несколько.Но лучший способ, кажется, использовать db.get_table(query,args)
функция. %q
является эффективной заменой ?
в представлении Android SQLite.Вот преобразование данного кода:
String query = "SELECT AsText(Transform(MakePoint(%q, %q, 4326), 32632));";
TableResult result=db.get_table(query,new String[]{""+TEST_LONG,""+TEST_LAT});
После этого вам просто нужно получить результаты из TableResult.Здесь нет вызова метода для получения результатов, вам фактически нужно получить публично объявленную переменную и вручную проанализировать ее.Вот пример того, как это можно сделать.
TableResult result=db.get_table(query,new String[]{""+lng,""+lat});
Vector<String[]> rows=result.rows;
for (String[] row:rows)
{
for (String val:row)
{
Log.v(TAG,val);
}
}
Если вы не делаете выбор, попробуйте что-то вроде этого:
TableResult result=new TableResult();
db.exec("ATTACH DATABASE %q AS newDb",result,new String[]{path});
Я предполагаю, что тот же шаблон будет работать для INSERTS и тому подобного.