I've a requirement in my android app.
There is an already existing database A which has a table T. From the next release of the app, I want to create a new database B and MOVE my table from A to B WITH all the existing data.
I am guessing there'd be some way to take dump from the existing db and store that in an asset file. And then use that file to restore the table in new db.
Can't store that data in-memory as it might go to inconsistent state if the app is killed in between.
I am not able to find any well-defined way to do this after spending some time searching in the docs/on the forums.
Please help.
You can achieve this by using ATTACH command of sqlite. First is by specifying the path of the first database.
private static String FIRST_DB_PATH = context.getDatabasePath("Sample.sqlite").toString();
Then you attach it to secondDb
SQLiteDatabase secondDB = secondDBHandler.getWritableDatabase();
secondDB.execSQL("ATTACH DATABASE '" + FIRST_DB_PATH + "' AS tempDb");
Then do the insert query. NOTE: You use secondDB as main
secondDB.execSQL("INSERT INTO main." + SeconDB_table_name + "SELECT * FROM tempDb."+ FirstDB_table_name );
Then finally detach the first db
secondDB.execSQL("DETACH tempDb");
Hope this helps
EDIT:
Do this for dropping table
secondDB.execSQL("DROP TABLE IF EXISTS main." + SeconDB_table_name);
Ok heres how to create a table for secondDB as a copy of the firstDb
secondDB.execSQL("CREATE TABLE main." + SeconDB_table_name + " AS SELECT * FROM tempDb." + FirstDB_table_name);
If what you mean in comment is to drop the first table after moving it to second table, then drop it before dettaching
secondDB.execSQL("DROP TABLE IF EXISTS tempDb." + FirstDB_table_name);
Related
I'm having trouble with a SELECT statement in my SQLite Database. When the part of the app relating to this SELECT statement is ran, the app closes. Below you will find a picture of my Database.
My SQLite Database Schema
Each time an expense is recorded the expense of course goes into the "expenses" table but it also goes into the "peoplexpenses" table. The expense when created, is entered multiple times into the "peoplexpenses" table as more than 1 person can be related to an expense (hence why the "peoplexpenses" table is there in the first place to prevent a Many-to-Many relationship). So what I'm trying to get is, the person's name along with all their related expenses added together to give a total for the person. Hope that makes sense.
My failing SQL statement is:
"SELECT P.name, sum(E.amount)
FROM " + TABLE_EXPENSES + " E, " + TABLE_PEOPLE + " P, " + TABLE_PEOPLEXPENSES + "PE
WHERE PE.pid = P.pid AND PE.eid = E.eid
GROUP BY P.name"
Please find the Create Table statements and new LogCat here: https://pastebin.com/8eP1BBCt
i tried to search in the sqlite database using the below code :
Cursor cusror;
cursor=db.rawQuery("SELECT * FROM "+ Contactsnew.TABLE02 + " WHERE "
+ Contactsnew.userid + " = " + Contactsnew.userId + " AND " +
Contactsnew.TITLE +
" LIKE '"+search.getText()+"%'");
its working successfully , but in huge database its working slowly. i searched the last days to find third library to work with my own database (Copied from assets to sqlite database) .
i find top five libraries in this article i followed each library but what i find each database is working only with the database that created by itself not with existing database (Already copied from assets).
any help to use any of these library and refer it to my own database or any another library to help me .
Thanks
I suggest creating prepared statements and re-use them. There is an excellent answer on Stack Overflow how to do that. Consider reducing the columns returned by the query, if not all columns are needed. Further, consider creating indexes for relevant columns. test would be the table name and id a column name:
CREATE INDEX idx01 ON test(id);
As a last resort it might be worth trying to remove the LIKE completely and to the regex test while iterating over your cursor.
You have to make sure existing database has the same format of data as new database you adding.
Probably, the simpliest solution here - write some 'migration utility', which will extract existing data and save it to new database.
To speed up queries store different aspects of data into separate tables (not everything in single table), or, if your data has many dependencies, try noSql database (Realm) which not using tables.
How to dynamically create table in database using greendao or ORMLite? I want to create new table in database when user pressed button, for each new table in database, data model is same but I need table with diffrent name. Is that possible ?
Concerning greendao:
It's not possible to dynamically create a new table. With greendao the code for handling your database is created on your development station by a J2SE-Application (using the daogenerator).
Concerning Ormlite:
I haven't been using Ormlite until now, but I doupt that generating new tables at runtime is possible.
Conclusion:
IMHO a database design, where you have to create new tables at runtime is bad practice, because you won't beable to benefit from ORM-frameworks. A design like that is also very difficult to maintain (if not impossible) and/or to test. On top of that a design like that may be difficult to understand for other developers as it is really uncommon.
Thus you should redesign your database schema.
You can use SQLite
public void createUserTable(DatabaseOperations d, String user) {
final SQLiteDatabase db = getWritableDatabase();
String CREATE_TABLE_NEW_USER = "CREATE TABLE " + user + " (" + UserInfo.NOTES + " TEXT)";
db.execSQL(CREATE_TABLE_NEW_USER);
db.close();
}
My app reads an XML file on the internet, takes note of the time and creates/writes an SQLite database. The next time data is required, if the time is >24hrs the database is updated (xml downloaded again).
The problem is that whenever I relaunch the app in AVD it has to re-download and so I notice that all the data in the database is written again (duplicated). So instead of 10 items, I have 20 (10+10 duplicates). If I relaunch again I get another 10 items duplicated.
I thought about how I could prevent the duplication of the database (or delete the old entries), so I decided to increment the database version every time the content is downloaded. I thought this would trigger the onUpgrade() method so the data would be cleared but nothing changes.
Now I am clueless. How should I go about this?
On your database create you'll want to use the UNIQUE constraint. You may not want the ON CONFLICT REPLACE that i use, but you should get the idea.
For Ex:
private static final String DATABASE_CREATE_NEWS= "create table news (_id integer primary key autoincrement, "title text not null, description text not null, date text not null, LastModified text not null, UNIQUE(title, date) ON CONFLICT REPLACE);";
Here is another solid thread that talks about it as well.
SQLite table constraint - unique on multiple columns
Here is some more info on the android sqlite: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
You should create an index on the columns that represent a unique identifier.
see this article on SQLite's website.
CREATE INDEX ix_tblexample ON TableName ( Column1, Column2, Column3 [, Column4, etc..])
Or (as per your comment) you can select the table into a cursor and check for each one.
String sql = "select * from " + tableName + "where column1 = " + param1 + "and column2 = " + param2;
Cursor cur = _db.rawQuery( sql, new String[0] );
if(cur.getCount() == 0)
{
//upload
}
At the moment I am having to write out each query to insert data into the database separately.
Is there a way I can import a spreadsheet or anything else and end up with this form.?
Is there an auto-increment feature like in normal MySQL?
db.execSQL("INSERT INTO " +
SAMPLE_TABLE_NAME +
" Values ('3','" +
"Question'," +
"'Answer1'," +
"'Answer2'," +
"'Answer3'," +
"'Answer4'," +
"'Correctanswer'," +
"'Reason');");
Also is there an autoincrement feature like in normal Mysql?
Yes. Take a look at: http://www.sqlite.org/autoinc.html
With regards to your original question; for those cases I better create the database and the initial data in my computer using any of the Sqlite DB Managers out there. Then, I put the database inside the assets directory of the project and instead of creating the database the normal way, I copy the database from there to the handset. This like could be helpful in that case:
http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/
If you can use the SQLite Command Line Shell to prepare your database, you can .import into a table from a file
If your data is (contained in) a spreadsheet, consider using the spreadsheets scripting/macro language to export table(s) INTO a SQLite database
For lots of tables preparing a master database and attach-ing to that from your app may be more efficient and could be done on the handset only
wrt to autoincrement, look at the autoincrement faq too
If I understand, you want to initialize your database with some values, but you don't want to hardcode each query.
In this case you should use JSON to store your data in an external file (like a spreadsheet), then parse this file to get your data and use it to generate your SQL queries.
Here is a tutorial on how to use JSON in android apps.