Multiple database operations from sql query - android

I have two instances of SQLiteDatabase database. And I need to copy data from one to another.
I need to execute this query:
INSERT INTO `toDB`.`tableName` SELECT * FROM `fromDB`.`tableName`
so, How can I do this my database instances? How to replace toDB and fromDB ?

Never tried that but it should work this way:
you have to ATTACH the other database at SQLite level so sqlite can access it directly.
For example you open the database that shall be the toDB and you issue the following command (via execSQL)
ATTACH DATABASE '/data/data/your.package/databases/dbname.db' AS fromDB
you should have access to the other database now and can do
INSERT INTO main.tableName SELECT * FROM fromDbB.tableName
the database you opened originally has the name "main" automatically.
You can and should get the path to your databases via Context#getDatabasePath since there is no guarantee that this path is the same on all devices.

Yes, you can do this as following:
DatabaseHelper dbHelper = DatabaseHelper.create(CMOSApplication.getInstance());
SQLiteDatabase db = null;
try {
db = dbHelper.getWritableDatabase();
db.execSQL("attach database ? as oldDB",
new String[] { CMOSApplication.getInstance().getDatabasePath("cmos_database").getPath() });
db.execSQL("insert into task select * from oldDB.task");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(db != null){
try {
db.execSQL("detach oldDB");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Related

Android Attach database onupgrade locks database

On upgrade method i'm renaming my database and copying new database from assets folder.
But on Attach statements it throws an exception on "database locked (code) 5"
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(oldVersion<newVersion){
db.close();
/**
* Renaming Database from Databse path
*
*/
new File(Constants.DATABASE_PATH+Constants.DATABSE_NAME).renameTo(new File(Constants.DATABASE_PATH+Constants.DATABASE_NAME_RENAME));
boolean mm = checkDataBase(Constants.DATABSE_NAME);
boolean up = checkDataBase(Constants.DATABASE_NAME_RENAME);
try {
copyDataBase();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
boolean dbmm = checkDataBase(Constants.DATABSE_NAME);
boolean dbup = checkDataBase(Constants.DATABASE_NAME_RENAME);
try{
String path = Constants.DATABASE_PATH+Constants.DATABSE_NAME;
db = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READWRITE);
File dbFile=myContext.getDatabasePath(Constants.DATABSE_NAME);
At the line below it throws database lock (code 5) expection.
db.execSQL(String.format("ATTACH DATABASE '%s' AS BACKUP;",
dbFile,null));
db.execSQL("INSERT INTO "+Constants.COMPANY_TABLE_NAME+" SELECT * FROM BACKUP."+Constants.COMPANY_TABLE_NAME);
db.execSQL("INSERT INTO "+Constants.PAGE_TABLE_NAME+" SELECT * FROM BACKUP."+Constants.PAGE_TABLE_NAME);
db.execSQL("INSERT INTO "+Constants.BOOKMARK_TABLE_NAME+" SELECT * FROM BACKUP."+Constants.BOOKMARK_TABLE_NAME);
db.execSQL("INSERT INTO "+Constants.CATALOG_TABLE_NAME+" SELECT * FROM BACKUP."+Constants.CATALOG_TABLE_NAME);
db.execSQL("INSERT INTO "+Constants.Order_Items_TABLE_NAME+" SELECT * FROM BACKUP."+Constants.Order_Items_TABLE_NAME);
db.execSQL("INSERT INTO "+Constants.Order_TABLE_NAME+" SELECT * FROM BACKUP."+Constants.Order_TABLE_NAME);
db.execSQL(String.format("DETACH DATABASE '%s' ;",
"BACKUP",null));
db.close();
}catch(Exception e){
Log.e("Db", e+"");
}
}
}
onUpgrade() (and onCreate()) are run inside a transaction; these methods must not do anything besides executing SQL statements inside that database.
If you are not interested in the contents of the old database, don't bother updating it. Just use a different file name for the new database, and delete the old file whenever you want.
If you are interested in the old data, you can attach and copy it after copying the new file.
(And consider using SQLiteAssetHelper.)
db.close();
doesn't need to close db manually.

Sugar ORM SUM a column

Does anyone know if it is possible to sum a column using Sugar ORM? I've tried to find any documentation, and there is a raw query method, however, the raw query method does not have any returning values.
Example: "select sum(price) from atable"
Class.executeQuery() is void.
Sugar ORM does not seem very usable until this kind of features (along with JOIN etc) are present.
I finally do it with the following code:
long sumValue = -1L;
Database db = ((Application)SugarApp.getSugarContext()).obtainDatabase();
SQLiteDatabase sqLiteDatabase = db.getDB();
SQLiteStatement sqLiteStatement = sqLiteDatabase.compileStatement(
"SELECT SUM(column_name) FROM table_name");
try {
sumValue = sqLiteStatement.simpleQueryForLong();
} catch (Exception var16) {
var16.printStackTrace();
} finally {
sqLiteStatement.close();
}
Also need to change the Application class to can access to the DataBase property because has protected access (don't forget to modify the manifest properly).
public class Application extends SugarApp {
public Database obtainDatabase(){
return getDatabase();
}
}
Hope it helps.
You can perform raw queries by accessing sugar database object by reflection:
int sumValue = -1;
Field f = null;
try {
f = SugarContext.getSugarContext().getClass().getDeclaredField("sugarDb");
f.setAccessible(true);
SugarDb db = (SugarDb) f.get(SugarContext.getSugarContext());
Cursor cursor = db.getDB().
rawQuery("Select Sum(COLUMN_NAME) as s from TABLE_NAME" , null);
if (cursor.moveToFirst())
sumValue = cursor.getInt(cursor.getColumnIndex("s"));
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
It does not seem possible at present time. I ended up using greenDAO instead, a much faster (not depending on reflection) solution which gives access to the SQLiteDatabase-object, enabling all kind of custom possibilities.
The answer might be too late, but it will help new comers, its pretty easy to query custom queries to the database in order to SUM or use any query you could obtain access to the Database by the following code:
SugarDb sugarDb = new SugarDb(context);
then its pretty straight forward to query the database for example you could do
SQLiteDatabase database = sugarDb.getDB();
SQLiteStatement query = database.compileStatement("SELECT SUM(AMOUNT) FROM EXPENSES_MODEL");
try {
total = query.simpleQueryForLong();
} catch (Exception e) {
e.printStackTrace();
} finally {
query.close();
}
notice the underscore in table name? its how Sugar ORM names our tables so please be careful when calling the table.
notice how the column name is capitalised? its because Sugar ORM capitalise each column.

Avoid sqliteAssetHelper to log error

Hi guys i'have problem with this little block of code
// Insert a new contact in database
public void insertInSignature(String TITLE_SI) {
try {
// Open Android Database
db = databaseHelper.getWritableDatabase();
ContentValues initialValues = new ContentValues();
initialValues.put("TITLE_SI", TITLE_SI);
db.insert("DELIVERY_SLIP", null, initialValues);
} catch (SQLException sqle) {
Log.e(TAG, "insertUser Error");
Log.e(TAG, "Exception : " + sqle);
} finally {
// Close Android Database
databaseHelper.close();
}
}
I have unique constraint on my table "DELIVERY_SLIP
So , when i'm trying to insert some row which already exist , it return some error like "Oh shit , you're inserting the same , i'm sorry men , i can't do it"
http://cdn.imghack.se/images/3b51afd07d1f1a8bd021c9e9dfc57e98.png
Here my log
It's this line
databaseHelper.close();
When database helper close , this return the log.
I just want to avoid to log it, I already tested with a tryCatch on sqliteConstraintException
But, nothing worked.
Thanks by advance
Instead of insert(), use insertWithOnConflict() with some conflict resolution algorithm appropriate for your use, such as SQLiteDatabase.CONFLICT_IGNORE.

Database insert not working on Android

Hi I'm doing an Android application and I have a database. I'm able to do queries but the inserts don't seem to be working. I have a table named profile with the fields "id", "name" and "original".
This is the method:
public void addProfile(String name)
{
myDataBase.rawQuery("INSERT INTO profile(name, original) values('"+name+"', '0')", null);
}
And what I'm doing:
DataBaseHelper myDbHelper = new DataBaseHelper(activity);
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.openDataBase();
} catch (SQLException sqle) {
throw sqle;
}
for(Profile p : profiles){
myDbHelper.addProfile(p.getName());
System.out.println("Commiting profile "+ p.getName());
In LogCat it correctly appears "Commiting profile test".
I'm opening the database with:
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
I've searched everywhere for the erro and I can't seem to find it. Is it because I have an "id" instead of "_id" on the table? Wouldn't that only affect the SELECTs? In my Selects I use select id as _id but in insert I don't know how to do it.
It is not allowed to use rawQuery to insert data. You should use execSQL

Android SQLite query is always empty

So right now I'm using this solution in my app Ship an application with a database
In my main activity, I just want to test to make sure that the database is working, so all I'm doing it a simply query to get some names, all I did was add 3 lines(commented where I added them):
DatabaseHelper myDbHelper;
SQLiteDatabase myDb = null;
myDbHelper = new DatabaseHelper(this);
/*
* Database must be initialized before it can be used. This will ensure
* that the database exists and is the current version.
*/
myDbHelper.initializeDataBase();
Cursor c;
String s = null;
try {
// A reference to the database can be obtained after initialization.
myDb = myDbHelper.getWritableDatabase();
//the next 3 lines are all I added
c = myDb.rawQuery("select name from breads", null);
s = c.getString(1);
c.close();
/*
* Place code to use database here.
*/
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
myDbHelper.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
myDb.close();
}
}
However, s just remains empty. If I do the exact same query select name from breads in the console, I will get data. Does anyone have any ideas?
myDb = myDbHelper.getWritableDatabase();
//the next 3 lines are all I added
c = myDb.rawQuery("select name from breads", null);
c.moveToFirst(); // ADD THIS
s = c.getString(1);
c.close();

Categories

Resources