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

Ошибка с БД

Добавлено: 06 фев 2014, 13:11
Артем Дегтев
При добавление большого количества записей в БД, выскакивает ошибка( наведена ниже). В моем случаи это больше 900 записей. Что может быть?

Вот логи с ошибкой
02-06 12:08:37.483: E/SQLiteLog(6694): (14) cannot open file at line 28379 of [00bb9c9ce4]
02-06 12:08:37.483: E/SQLiteLog(6694): (14) os_unix.c:28379: (24) open(/data/data/com.example.radio/databases) -
02-06 12:08:40.643: E/SQLiteLog(6694): (14) cannot open file at line 30245 of [00bb9c9ce4]
02-06 12:08:40.643: E/SQLiteLog(6694): (14) os_unix.c:30245: (24) open(/data/data/com.example.radio/databases/DataBaseRadio24.db-journal) -
02-06 12:08:40.643: E/SQLiteLog(6694): (14) cannot open file at line 30245 of [00bb9c9ce4]
02-06 12:08:40.643: E/SQLiteLog(6694): (14) os_unix.c:30245: (24) open(/data/data/com.example.radio/databases/DataBaseRadio24.db-journal) -
02-06 12:08:40.643: E/SQLiteLog(6694): (14) statement aborts at 20: [SELECT * FROM NewsRadio24 WHERE UpdateDate = ?] unable to open database file
02-06 12:08:40.653: E/SQLiteQuery(6694): exception: unable to open database file (code 14); query: SELECT * FROM NewsRadio24 WHERE UpdateDate = ?
02-06 12:08:40.653: E/AndroidRuntime(6694): FATAL EXCEPTION: Thread-10016
02-06 12:08:40.653: E/AndroidRuntime(6694): android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)
02-06 12:08:40.653: E/AndroidRuntime(6694): at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
02-06 12:08:40.653: E/AndroidRuntime(6694): at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:969)
02-06 12:08:40.653: E/AndroidRuntime(6694): at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
02-06 12:08:40.653: E/AndroidRuntime(6694): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
02-06 12:08:40.653: E/AndroidRuntime(6694): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143)
02-06 12:08:40.653: E/AndroidRuntime(6694): at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
02-06 12:08:40.653: E/AndroidRuntime(6694): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:196)
02-06 12:08:40.653: E/AndroidRuntime(6694): at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:236)
02-06 12:08:40.653: E/AndroidRuntime(6694): at com.example.radio.MainActivity$ItemInBDatDate.run(MainActivity.java:909)

Re: Ошибка с БД

Добавлено: 06 фев 2014, 13:14
anber
А что за база, откуда взялась, где лежит, как добавляешь записи?
Если мало записей добавляешь то ошибки нет?

Re: Ошибка с БД

Добавлено: 06 фев 2014, 13:19
Артем Дегтев
anber писал(а):А что за база, откуда взялась, где лежит, как добавляешь записи?
Если мало записей добавляешь то ошибки нет?
Спасибо за ответ.
Если мало добавляю то ошибки нет, только после 900 записей.

Вот поток который добавляет

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

public AddNews(String date, String DataAfterDate) {
			if (date == "now")
				LinkForNews = "http://radio24.ua/feeds/newsList.do";
			else {
				LinkForNews = "http://radio24.ua/feeds/newsList.do?fromTime=";
				LinkForNews = LinkForNews.concat(date);
				LinkForNews = LinkForNews.concat("&older=true");
			}
			dd = DataAfterDate;
		}

		public void run() {
			if(!AddingNews){
				AddingNews = true;
				Log.e("AddNews", "Start add news");
			if (InternetConnection()) {
				JSONParser jParser = new JSONParser();
				JSONObject jObject = jParser.getJSONFromUrl(LinkForNews);
				JSONArray jArray = new JSONArray();
				try {
					jArray = jObject.getJSONArray("radio24");
					for (int i = 0; i < jArray.length(); i++) {
						JSONObject jLocalObject = jArray.getJSONObject(i);
						id_news = jLocalObject.getInt("id");
						name_news = jLocalObject.getString("name");
						annotation_news = jLocalObject.getString("annotation");
						summary_news = jLocalObject.getString("summary");
						updateDate_news = jLocalObject.getString("updatedDate");
						imgnormalPath = jLocalObject.getString("imgnormalPath");
						imgsmallPath = jLocalObject.getString("imgsmallPath");
						InputStream is = (InputStream) new URL(imgsmallPath)
								.getContent();
						smallImage = Drawable.createFromStream(is, "srcName");
						AddToBD(id_news, name_news, annotation_news,
								summary_news, updateDate_news, imgsmallPath,
								imgnormalPath, DrawableToBlob(smallImage), null);

					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				BDInListView d = new BDInListView(dd);
				d.start();
				while (d.isAlive()) {
				}
				
				
			}
			
		}				Log.e("AddNews", "Finish add news");

			AddingNews = false;
			}
	}

Вот клас БД

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

package com.example.radio;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;


public class ClassForBD extends SQLiteOpenHelper {
	// константы для конструктора
		private static final String DB_NAME = "DataBaseRadio24.db";
		private static final int DB_VERSION = 1;
	public ClassForBD(Context context) {
		super(context, DB_NAME, null, DB_VERSION);
		
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		db.execSQL("create table NewsRadio24 ("
		          + "ID_In_Site integer,"
		          + "Name text,"
		          + "Annotation text,"
		          + "Summary text,"
		          + "UpdateDate text,"
		          + "SmallImagePath text,"
		          + "NormalImagePath text,"
		          + "SmallImage blob,"
		          + "NormalImage blob"
		          + ");");
	
	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub

	}
}


Функция добавления в БД

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

	public void AddToBD(int id, String name, String annotation, String summary,
			String updateDate, String SmallImagePath, String NormalImagePath,
			byte[] smallImageBlob, byte[] normImageBlob) {

		SQLiteDatabase BD = DBClass.getWritableDatabase();
		ContentValues cv = new ContentValues();
		cv.put("Id_In_Site", id);
		cv.put("Name", name);
		cv.put("Annotation", annotation);
		cv.put("Summary", summary);
		cv.put("UpdateDate", StringToMilisec(updateDate));
		cv.put("SmallImagePath", SmallImagePath);
		cv.put("NormalImagePath", NormalImagePath);
		cv.put("SmallImage", smallImageBlob);
		cv.put("NormalImage", normImageBlob);
		BD.insert("NewsRadio24", null, cv);
		cv.clear();
	}

Re: Ошибка с БД

Добавлено: 06 фев 2014, 13:36
anber
На чем тестишь? Емулятор или какой девайс?

Re: Ошибка с БД

Добавлено: 06 фев 2014, 14:02
anber
Я не знаю почему оно падает, первая мысль - попробовать вставить все данные в одной транзакции, типа:

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

 db.beginTransaction();
        try {
            addItems();
            db.setTransactionSuccessful();

        }catch {
            //Error in between database transaction 
        }finally {
                db.endTransaction();

        }

Re: Ошибка с БД

Добавлено: 06 фев 2014, 14:55
Foenix
да, добавлять нужно в транзакции.
плюс у тебя два блоба (что очень нехорошо), проверь, может макс объем бд достигнут. Картинки нужно записывать на диск, а в таблицу записывать путь к ней.

Re: Ошибка с БД

Добавлено: 06 фев 2014, 15:52
Артем Дегтев
Спасибо за ответы.
Вставил транзакцию нечего не изменилось.
Тестирую на разных девайсах, вылетает на одном количестве, думаю падает из-за того что достигаю максимальный размер. Буду проверять, потом еще отпищусь.

Re: Ошибка с БД

Добавлено: 06 фев 2014, 15:57
anber
Как минимум это должно значительно улучшить время, судя по: http://stackoverflow.com/a/16177822/1159507

Re: Ошибка с БД

Добавлено: 06 фев 2014, 16:03
altwin
Артем Дегтев писал(а):Спасибо за ответы.
Вставил транзакцию нечего не изменилось.
Тестирую на разных девайсах, вылетает на одном количестве, думаю падает из-за того что достигаю максимальный размер. Буду проверять, потом еще отпищусь.
может я не в тему, потому, как информацией в полной мере не владею.. но помнится мне в свое время я переходил на postgreSQL и убегал от MySQL именно по причине того, что последняя имела ограничение на транзакции и там это ограничение очень раздражало, когда нельзя было вставить нужные записи... почему то мне кажется, что sqlite3 тоже должна быть очень печальна в этом плане.

Re: Ошибка с БД

Добавлено: 06 фев 2014, 16:05
altwin
я бы советовал с этим познакомиться: http://ru.wikipedia.org/wiki/SQLite#.D0 ... 0.B8.D1.8F
почему то мне кажется, что вот этих не новых "правил" стоит придерживаться: http://docs.blackberry.com/en/developer ... 781_11.jsp

Re: Ошибка с БД

Добавлено: 06 фев 2014, 16:21
anber
Еще советую просмотреть все ответы на тут: http://stackoverflow.com/questions/1609 ... e-database

Re: Ошибка с БД

Добавлено: 06 фев 2014, 17:18
anber
Мне уже даже интересно как ты этого добился, я уже и так и эдак делаю insert, и по 10'000 а оно работает...
Может у тебя к базе еще кто-то параллельно в другом потоке обращается?

Re: Ошибка с БД

Добавлено: 06 фев 2014, 17:23
altwin
anber писал(а):Мне уже даже интересно как ты этого добился, я уже и так и эдак делаю insert, и по 10'000 а оно работает...
Может у тебя к базе еще кто-то параллельно в другом потоке обращается?
тут дело в том, что нужно не просто insert, а в ту же структуру таблицы писать те же данные, мне кажется нарушается что то из этих условий, хотя фиг его знает...

Описание Значение Константа в исходнике
Максимальная длина строки или BLOB-поля 1 000 000 000 SQLITE_MAX_LENGTH
Максимальное количество колонок 2 000 SQLITE_MAX_COLUMN
Максимальная длина SQL-выражения 1 000 000 SQLITE_MAX_SQL_LENGTH
Максимальное количество таблиц в выражениях с JOIN 64
Максимальная глубина дерева выражений 1 000 SQLITE_MAX_EXPR_DEPTH
Максимальное количество аргументов функции 100 SQLITE_MAX_FUNCTION_ARG
Максимальное количество термов в объединённом выражении с SELECT 500 SQLITE_MAX_COMPOUND_SELECT
Максимальная длина шаблона как аргумента операторов LIKE или GLOB 50 000 SQLITE_MAX_LIKE_PATTERN_LENGTH
Максимальное количество символов-заменителей в одном SQL-выражении 999 SQLITE_MAX_VARIABLE_NUMBER
Максимальная глубина рекурсии триггеров 1 000 SQLITE_MAX_TRIGGER_DEPTH
Максимальное количество присоединённых баз 10 SQLITE_MAX_ATTACHED
Максимальный размер страницы базы данных 32 768 SQLITE_MAX_PAGE_SIZE
Максимальное количество страниц в файле базы данных 1 073 741 823 SQLITE_MAX_PAGE_COUNT

Re: Ошибка с БД

Добавлено: 06 фев 2014, 17:29
anber
Тут, http://habrahabr.ru/post/125883/, в конце статьи расписана ошибка "Unable to open database file"

Re: Ошибка с БД

Добавлено: 06 фев 2014, 17:29
Артем Дегтев
anber писал(а):Мне уже даже интересно как ты этого добился, я уже и так и эдак делаю insert, и по 10'000 а оно работает...
Может у тебя к базе еще кто-то параллельно в другом потоке обращается?
Возможно есть обращения с других потоков, это может вызвать такую ошибку?

Re: Ошибка с БД

Добавлено: 06 фев 2014, 17:32
anber
altwin писал(а):
anber писал(а):Мне уже даже интересно как ты этого добился, я уже и так и эдак делаю insert, и по 10'000 а оно работает...
Может у тебя к базе еще кто-то параллельно в другом потоке обращается?
тут дело в том, что нужно не просто insert, а в ту же структуру таблицы писать те же данные, мне кажется нарушается что то из этих условий, хотя фиг его знает...
Разве что оно собирает все эти инсерты в одно SQL-выражение...

Re: Ошибка с БД

Добавлено: 06 фев 2014, 17:33
anber
Артем Дегтев писал(а):
anber писал(а):Мне уже даже интересно как ты этого добился, я уже и так и эдак делаю insert, и по 10'000 а оно работает...
Может у тебя к базе еще кто-то параллельно в другом потоке обращается?
Возможно есть обращения с других потоков, это может вызвать такую ошибку?
Это не просто может вызвать такую ошибку, это гарантированно вызовет такую ошибку.

Re: Ошибка с БД

Добавлено: 06 фев 2014, 17:33
altwin
вообще да стоит попробывать сделать запись в базу не стандартными средствами, а с помощью ORMLite например, будет ли ошибка...

Re: Ошибка с БД

Добавлено: 06 фев 2014, 17:36
altwin
anber писал(а):
Артем Дегтев писал(а):
anber писал(а):Мне уже даже интересно как ты этого добился, я уже и так и эдак делаю insert, и по 10'000 а оно работает...
Может у тебя к базе еще кто-то параллельно в другом потоке обращается?
Возможно есть обращения с других потоков, это может вызвать такую ошибку?
Это не просто может вызвать такую ошибку, это гарантированно вызовет такую ошибку.
я бы сказал, в таком случае странно что 900 записей уже сделанно и ошибки так долго не было )))))) Проще всего проверить, класс БД в синглтон превратить, если ошибки не будет - все ясно.

Re: Ошибка с БД

Добавлено: 06 фев 2014, 17:39
anber
altwin писал(а):я бы сказал, в таком случае странно что 900 записей уже сделанно и ошибки так долго не было )))))) Проще всего проверить, класс БД в синглтон превратить, если ошибки не будет - все ясно.
мутное это дело, мутное...