我将“food_db.sql”文件存储在/ res / raw文件夹中, 它里面有很多“插入”。
我的问题是如何在我的Android应用程序中执行该文件并将数据导入sqlite数据库?
这是我的数据库代码。任何建议?
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);
}
}
答案 0 :(得分:26)
我特意为你写了这个< 3
我使用与“/ raw / food_db.sql”相同的文件名,但导致错误,而我必须将其称为“/ raw / food_db“即可。我猜它是因为你没有在你的代码中使用文件名,但是像“R.raw.food_db”这样写的ResourceIds和点使系统混乱。
在你的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();
}
享受!
哦..顺便说一句:这段代码适用于每个insert-Statement都有自己的行的文件。
答案 1 :(得分: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无法正常工作的原因。
答案 2 :(得分:1)
在一个字符串中插入所有行:
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;
}
答案 3 :(得分:1)
最好的方法是解析sql文件,将文件拆分为语句列表。
这并不难,因为我们只需要处理提交,字符串和转义,但是在短时间内写一个也不容易。
我从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字符串中使用“ / *”,“-”),但是在大多数情况下都可以。
希望获得帮助