SQLiteStatement выполняет SELECT/INSERT/DELETE/UPDATE

Я использую скомпилированный SQLiteStatement с транзакциями для оптимизации транзакций SQLite, но я читаю документацию для execute:

Выполните эту инструкцию SQL, если это не SELECT / INSERT / DELETE / UPDATE, например, CREATE / DROP table, view, trigger, index и т. д.

Кажется, это означает, что эту функцию нельзя использовать с операторами SELECT / INSERT / DELETE / UPDATE, но у меня есть код, который использует ее со вставкой и работает.

Я знаю о executeInsert и других методах, но executeUpdateDelete недоступен на моем уровне API, могу ли я использовать execute?

Кроме того, если мне не нужен последний идентификатор вставки или количество затронутых строк, следует ли использовать execute вместо executeInsert и т. д., другими словами, это более эффективно?


person Emil Davtyan    schedule 13.11.2012    source источник


Ответы (2)


execute, вероятно, не быстрее, чем executeInsert, может быть даже медленнее (в ICS execute вызывает executeUpdateDelete и отбрасывает возвращаемое значение). Вам нужно проверить это, но я сомневаюсь, что вы найдете здесь реальную разницу.

Насколько я знаю, безопасно использовать только execute, если вам не нужны возвращаемые значения, но я бы не стал рассчитывать на то, что это останется верным в будущих версиях Android. В документации сказано, что нет, поэтому, возможно, кто-то собирается изменить поведение, чтобы отразить это. Более старые реализации, похоже, тоже используют execute (например, 2.1 delete() исходный код). Например, Jelly Bean изменил значительно за кулисами SQLite, но все равно должно работать при использовании execute

Кроме того, если вы не используете один и тот же SQLiteStatement снова и снова, просто перепривязывая аргументы, вероятно, не стоит его использовать. Создание нового каждый раз, когда вы вызываете обычные методы insert, update, ..., выполняется быстро по сравнению с фактическим доступом к базе данных и требуемым дисковым вводом-выводом. С другой стороны, транзакции очень помогают, поскольку синхронизация состояния базы данных на диске для каждого оператора выполняется очень медленно.

person zapl    schedule 13.11.2012
comment
Таким образом, вы имеете в виду, что нет никакой гарантии, что execute() будет работать в будущем, выпущенном также с INSERT statement, и документы просто сбивают с толку, говоря, что это Execute this SQL statement, if it is not a SELECT / INSERT /...., тогда он не должен выполнять INSERT (потому что это только утверждение, которое я тестировал) и оно работает! И спасибо за ценную информацию :) - person Muhammad Babar; 20.11.2014
comment
Также statement.executeUpdateDelete(); это доступно в API 11, есть обходной путь для 2.2? - person Muhammad Babar; 20.11.2014
comment
@MuhammadBabar Документация пытается сказать вам, что метод execute не предназначен для операторов, которые имеют результат. Например, набор строк для выбора, количество изменений для обновления/удаления или идентификатор последней строки для вставки. На данный момент нет кода, препятствующего тому, чтобы эти непреднамеренные операторы работали. Может быть, будущие изменения в архитектуре базы данных будут, я не знаю. Инженеры платформы Android могут легко добавить такое изменение без предварительного уведомления, потому что описание метода предупреждает вас, что он не будет работать годами. - person zapl; 20.11.2014
comment
В версии 2.2 единственный способ получить результирующее количество изменений оператора обновления/удаления — использовать SQLiteDatabase#update или delete. Эти методы используют новый SQLiteStatement вызов метода для внутреннего использования. И они используют SQLiteStatement#execute(), но затем записывают количество изменений с помощью скрытого метода SQLiteDatabase. Этот скрытый метод, наконец, представлен в API 11 для SQLiteStatement использования, но не раньше. - person zapl; 20.11.2014
comment
Какой из них быстрее delete() или executeUpdateDelete()? - person Muhammad Babar; 06.02.2015
comment
@MuhammadBabar не стесняйтесь профилировать, но это не имеет значения, поскольку узким местом в SQL является дисковый ввод-вывод, который намного медленнее, чем несколько строк кода, которые отличаются. Используйте тот, который производит более чистый код, когда сомневаетесь. - person zapl; 09.02.2015
comment
Спасибо, но я сделал тест, удалив более 18 000 записей. Тот, который я считаю эффективным и быстрым, заключался в использовании delete() с transactions. - person Muhammad Babar; 09.02.2015

Используйте SQLiteDatabase вместо SQLiteStatement для взаимодействия с вашей базой данных. SQLiteStatements не являются потокобезопасными, поэтому я бы не использовал их для SELECT/INSERT/DELETE/UPDATE. Также вы должны стараться не использовать необработанные запросы к базе данных для чего-либо, кроме Selects. Есть встроенные вспомогательные функции, которые увеличат производительность вашей базы данных. В вашем экземпляре SQLiteDatabase у вас есть .insert, .update, .delete, и я использую .rawQuery для выбора.

person JustinMorris    schedule 13.11.2012
comment
но отсутствие THREAD-SAFE подразумевает только многопоточное приложение. Для одного потока стоит использовать, если вы хотите массовую вставку. - person Muhammad Babar; 20.11.2014
comment
гм, каждое приложение с БД должно быть многопоточным. Любой запрос к диску, БД или веб-службе должен быть отключен от потока пользовательского интерфейса. Если вы блокируете поток пользовательского интерфейса для массовых вставок, вы делаете это неправильно. - person JustinMorris; 23.11.2014
comment
@JustinMorris: если к БД обращается только один рабочий поток, можно вызывать не потокобезопасные методы. Тот факт, что приложение является многопоточным, не является проблемой именно по той причине, что основной поток не обращается к БД. - person Dabbler; 31.12.2016