Android, как выполнить sql файл в sqlitedatabase
У меня есть файл "food_db.sql", хранящийся в папке /res/raw,
у него есть тонны "вставки".
Мой вопрос: как я могу выполнить файл и получить данные в sqlite databse в моем приложении Android?
вот код базы данных. любые предложения?
private static class DbHelper extends SQLiteOpenHelper{
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" +
KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_NAME + " TEXT NOT NULL, " +
KEY_HOTNESS + " TEXT NOT NULL);");
// how do i exec the sql file and get the data into this DB table?
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS" + DATABASE_TABLE);
db.execSQL("DROP TABLE IF EXISTS" + RECORD_TABLE);
onCreate(db);
}
}
Ответы
Ответ 1
Я написал это специально для вас < 3
Я использовал то же имя файла, что и "/raw/food_db.sql" , но привести к ошибкам, вместо этого мне пришлось называть его "/raw/food_db" . Я думаю, это потому, что вы не используете имена файлов в своем коде, но ResourceIds, которые написаны как "R.raw.food_db" и точка, путают систему.
Внутри вашего DbSource существует метод... предполагая, что есть такой код:
private SQLiteDatabase db;
...
DbHelper dbHelper = new DbHelper(context);
this.db = dbHelper.getWritableDatabase();
Вы помещаете этот метод там:
/**
* This reads a file from the given Resource-Id and calls every line of it as a SQL-Statement
*
* @param context
*
* @param resourceId
* e.g. R.raw.food_db
*
* @return Number of SQL-Statements run
* @throws IOException
*/
public int insertFromFile(Context context, int resourceId) throws IOException {
// Reseting Counter
int result = 0;
// Open the resource
InputStream insertsStream = context.getResources().openRawResource(resourceId);
BufferedReader insertReader = new BufferedReader(new InputStreamReader(insertsStream));
// Iterate through lines (assuming each insert has its own line and theres no other stuff)
while (insertReader.ready()) {
String insertStmt = insertReader.readLine();
db.execSQL(insertStmt);
result++;
}
insertReader.close();
// returning number of inserted rows
return result;
}
Вызвать это так (я попробовал из Activity, так что Toasts может выводить сообщения). Посмотрите внимательно, ошибки также "поджарены".
try {
int insertCount = database.insertFromFile(this, R.raw.food_db);
Toast.makeText(this, "Rows loaded from file= " + insertCount, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
Наслаждайтесь!
Oh.. btw: Этот код предназначен для файла, в котором каждый insert-Statement имеет свою собственную строку.
Ответ 2
@Override
public void onCreate(SQLiteDatabase db) {
InputStream is = null;
try {
is = context.getResources().openRawResource(R.raw.database_init);
String initSql = IOUtils.toString(is);
db.execSQL(initSql);
} catch (IOException e) {
Log.e(TAG, "Error loading init SQL from raw", e);
} catch (SQLException e) {
Log.e(TAG, "Error executing init SQL", e);
} finally {
IOUtils.closeQuietly(is);
}
}
Важная выноска: SQLiteDatabase.execSQL(String sql) выполняет только один оператор SQL, несколько операторов, разделенных точкой с запятой, не поддерживаются.
Я пытался с трудом узнать, почему моя database_init.sql не работает должным образом.
Ответ 3
Вставьте всю строку в одну строку:
public int insertFromFile(Context context, int resourceId) throws IOException {
// Reseting Counter
int result = 0;
// Open the resource
InputStream insertsStream = context.getResources().openRawResource(resourceId);
BufferedReader insertReader = new BufferedReader(new InputStreamReader(insertsStream));
// Iterate through lines (assuming each insert has its own line and theres no other stuff)
String insertStmt = "";
while (insertReader.ready()) {
insertStmt += insertReader.readLine();
result++;
}
insertReader.close();
db.execSQL(insertStmt);
// returning number of inserted rows
return result;
}
Ответ 4
Лучший способ - это анализ файла sql, разделить файл на список операторов.
Это не сложно, потому что нам нужно только позаботиться о коммите, строке и escape, но это не так просто написать за короткое время.
Я нашел простой способ заархивировать это, заменив строку комментария с помощью регулярных выражений из исходного кода SugarORM (https://github.com/chennaione/sugar/blob/master/library/src/main/java/com/orm/util/MigrationFileParser.java)
public MigrationFileParser(String content){
this.content = content.replaceAll("(\\/\\*([\\s\\S]*?)\\*\\/)|(--(.)*)|(\n)","");
}
public String[] getStatements(){
return this.content.split(";");
}
Этот способ имеет ограничение (мы не можем использовать "/*", "-" в строке sql), но в большинстве случаев все будет в порядке.
надеюсь, это поможет