Как использовать подготовленные инструкции в SQlite в Android?

Как использовать подготовленные инструкции в SQlite в Android?

Я все время использую готовые заявления в Android, это довольно просто:

SQLiteDatabase db = dbHelper.getWritableDatabase(); SQLiteStatement stmt = db.compileStatement("SELECT * FROM Country WHERE code = ?"); stmt.bindString(1, "US"); stmt.execute(); 

Для подготовленных операторов SQLite в Android есть SQLiteStatement . Подготовленные заявления помогают ускорить работу (особенно для операторов, которые нужно выполнять несколько раз), а также помогают избежать атак на атаку. См. Эту статью для общей дискуссии о подготовленных заявлениях.

SQLiteStatement предназначен для использования с операторами SQL, которые не возвращают несколько значений. (Это означает, что вы не будете использовать их для большинства запросов.) Ниже приведены некоторые примеры:

Создать таблицу

 String sql = "CREATE TABLE table_name (column_1 INTEGER PRIMARY KEY, column_2 TEXT)"; SQLiteStatement stmt = db.compileStatement(sql); stmt.execute(); 

Метод execute() не возвращает значение, поэтому его следует использовать с CREATE и DROP, но не предназначено для использования с SELECT, INSERT, DELETE и UPDATE, потому что они возвращают значения. (Но см. Этот вопрос .)

Вставить значения

 String sql = "INSERT INTO table_name (column_1, column_2) VALUES (57, 'hello')"; SQLiteStatement statement = db.compileStatement(sql); long rowId = statement.executeInsert(); 

Обратите внимание, что executeInsert() метод executeInsert() а не execute() . Конечно, вы не хотели бы всегда вводить одни и те же вещи в каждой строке. Для этого вы можете использовать привязки .

 String sql = "INSERT INTO table_name (column_1, column_2) VALUES (?, ?)"; SQLiteStatement statement = db.compileStatement(sql); int intValue = 57; String stringValue = "hello"; statement.bindLong(1, intValue); // 1-based: matches first '?' in sql string statement.bindString(2, stringValue); // matches second '?' in sql string long rowId = statement.executeInsert(); 

Обычно вы используете подготовленные инструкции, когда хотите быстро повторить что-то (например, INSERT) много раз. Подготовленный оператор делает так, что SQL-запрос не должен анализироваться и скомпилироваться каждый раз. Вы можете ускорить работу, используя транзакции . Это позволяет сразу применить все изменения. Вот пример:

 String stringValue = "hello"; try { db.beginTransaction(); String sql = "INSERT INTO table_name (column_1, column_2) VALUES (?, ?)"; SQLiteStatement statement = db.compileStatement(sql); for (int i = 0; i < 1000; i++) { statement.clearBindings(); statement.bindLong(1, i); statement.bindString(2, stringValue + i); statement.executeInsert(); } db.setTransactionSuccessful(); // This commits the transaction if there were no exceptions } catch (Exception e) { Log.w("Exception:", e); } finally { db.endTransaction(); } 

Ознакомьтесь с этими ссылками для получения более подробной информации о транзакциях и ускорения вставки баз данных.

  • Atomic Commit В SQLite (подробное объяснение, перейдите к части 3)
  • Транзакции базы данных
  • Пример добавления и обновления Android SQLite
  • Пример транзакции Android SQLite с заявлением, подготовленным INSERT
  • Перезагрузите свои вставки SQLite на Android
  • https://stackoverflow.com/a/8163179/3681880

Обновить строки

Это основной пример. Вы также можете применить концепции из раздела выше.

 String sql = "UPDATE table_name SET column_2=? WHERE column_1=?"; SQLiteStatement statement = db.compileStatement(sql); int id = 7; String stringValue = "hi there"; statement.bindString(1, stringValue); statement.bindLong(2, id); int numberOfRowsAffected = statement.executeUpdateDelete(); 

Удалить строки

Метод executeUpdateDelete() также может использоваться для операторов DELETE и был введен в API 11. См. Это вопросы и ответы .

Вот пример.

 try { db.beginTransaction(); String sql = "DELETE FROM " + table_name + " WHERE " + column_1 + " = ?"; SQLiteStatement statement = db.compileStatement(sql); for (Long id : words) { statement.clearBindings(); statement.bindLong(1, id); statement.executeUpdateDelete(); } db.setTransactionSuccessful(); } catch (SQLException e) { Log.w("Exception:", e); } finally { db.endTransaction(); } 

запрос

Обычно, когда вы запускаете запрос, вы хотите вернуть курсор с большим количеством строк. Однако это не то, что для SQLiteStatement . Вы не запускаете запрос с ним, если только вам нужен простой результат, например количество строк в базе данных, которое вы можете сделать с помощью simpleQueryForLong()

 String sql = "SELECT COUNT(*) FROM table_name"; SQLiteStatement statement = db.compileStatement(sql); long result = statement.simpleQueryForLong(); 

Обычно вы запускаете метод query() SQLiteDatabase, чтобы получить курсор.

 SQLiteDatabase db = dbHelper.getReadableDatabase(); String table = "table_name"; String[] columnsToReturn = { "column_1", "column_2" }; String selection = "column_1 =?"; String[] selectionArgs = { someValue }; // matched to "?" in selection Cursor dbCursor = db.query(table, columnsToReturn, selection, selectionArgs, null, null, null); 

См. Этот ответ для получения более подробной информации о запросах.

Если вы хотите, чтобы курсор возвращался, вы можете рассмотреть что-то вроде этого:

 SQLiteDatabase db = dbHelper.getWritableDatabase(); public Cursor fetchByCountryCode(String strCountryCode) { /** * SELECT * FROM Country * WHERE code = US */ return cursor = db.query(true, "Country", /**< Table name. */ null, /**< All the fields that you want the cursor to contain; null means all.*/ "code=?", /**< WHERE statement without the WHERE clause. */ new String[] { strCountryCode }, /**< Selection arguments. */ null, null, null, null); } /** Fill a cursor with the results. */ Cursor c = fetchByCountryCode("US"); /** Retrieve data from the fields. */ String strCountryCode = c.getString(cursor.getColumnIndex("code")); /** Assuming that you have a field/column with the name "country_name" */ String strCountryName = c.getString(cursor.getColumnIndex("country_name")); 

Посмотрите на этот fragment Genscripts, если вы хотите получить более полную версию . Обратите внимание, что это параметризованный SQL-запрос, поэтому, по сути, это подготовленный оператор.

Пример jasonhudgins не будет работать. Вы не можете выполнить запрос с помощью stmt.execute() и вернуть значение (или Cursor ).

Вы можете только предварительно скомпилировать утверждения, которые либо не возвращают никакие строки вообще (например, вставку, либо создание оператора таблицы), либо одну строку и столбец (и используют simpleQueryForLong() или simpleQueryForString() ).

Чтобы получить курсор, вы не можете использовать compiledStatement. Однако, если вы хотите использовать полностью подготовленный оператор SQL, я рекомендую адаптировать метод db.rawQuery() … Использование db.rawQuery() вместо db.query() .

Давайте будем гением компьютера.