I want to add columns to table, i search before topics.
Seem they like to alert table. But i perfer to create new table.
So I try to do like this
`
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("create table tmp_talbe name VARCHAR(50),number integer,number2 integer");
db.execSQL("insert into tmp_table select * from origin_table");
db.execSQL("drop if exists table origin_table");
db.execSQL("alter tmp_talbe rename to origin_talbe");
}`
I have problem in copy old table data to new table.If i have 2 columns in old table, 3 colums in new table,
.It will show error 3 columns in tmp_table, but only 2 supplier.
Seem code line 2 can't do like this,how to modify is better?
You got the error because 'select * from origin_table' only return 2 columns, NOT 3 columns and tmp_table has 3 columns.
I assume that the original table columns: NAME, Number1 and You want to add Number2 as third column:
Change
db.execSQL("insert into tmp_table select * from origin_table");
To
db.execSQL("insert into tmp_table select NAME, Number1, NULL as Number2 from origin_table");
Use NULL for third column when you copy data from Original table to Temp table.
You can also use any Default data for Third column.
Related
I have an application, where I am detecting the type of a particular column at run-time, on page load. Please refer the below code:
public String fncCheckColumnType(String strColumnName){
db = this.getWritableDatabase();
String strColumnType = "";
Cursor typeCursor = db.rawQuery("SELECT typeof (" + strColumnName +") from tblUsers, null);
typeCursor.moveToFirst();
strColumnType = typeCursor.getString(0);
return strColumnType;
}
The above method simply detects the type of column with column Name 'strColumnName'. I am getting the type of column in this case.
Now, I want to change the column type to TEXT if I am receiving INTEGER as the column type. For this, I tried the below code:
public String fncChangeColumnType(String strColumnName){
db = this.getWritableDatabase();
String newType = "";
Cursor changeCursor = db.rawQuery("ALTER TABLE tblUsers MODIFY COLUMN " + strColumnName + " TEXT", null);
if (changeCursor != null && changeCursor.moveToFirst()){
newType = changeCursor.getString(0);
}
return newType;
}
But while executing the 'fncChangeColumnType' method, I am getting this error, android.database.sqlite.SQLiteException: near "MODIFY": syntax error (code 1): , while compiling: ALTER TABLE tblUsers MODIFY COLUMN UserID TEXT
NOTE: I also replaced 'MODIFY' with 'ALTER', but still getting the same error.
Please check if this is the right method to change the type dynamically.
Please respond back if someone has a solution to this.
Thanks in advance.
In brief, the solution could be :-
Do nothing (i.e. take advantage of SQLite's flexibility)
you could utilise CAST e.g. CAST(mycolumn AS TEXT) (as used below)
Create a new table to replace the old table.
Explanations.
With SQLite there are limitations on what can be altered. In short you cannot change a column. Alter only allows you to either rename a table or to add a column. As per :-
SQL As Understood By SQLite - ALTER TABLE
However, with the exception of a column that is an alias of the rowid column
one defined with ?? INTEGER PRIMARY KEY or ?? INTEGER PRIMARY KEY AUTOINCREMENT or ?? INTEGER ... PRIMARY KEY(??) (where ?? represents a valid column name)
you can store any type of value in any type of column. e.g. consider the following (which stores an INTEGER, a REAL, a TEXT, a date that ends up being TEXT and a BLOB) :-
CREATE TABLE IF NOT EXISTS example1_table (col1 BLOB);
INSERT INTO example1_table VALUES (1),(5.678),('fred'),(date('now')),(x'ffeeddccbbaa998877665544332211');
SELECT *, typeof(col1) FROM example1_table;
The result is :-
As such is there a need to change the column type at all?
If the above is insufficient then your only option is to create a new table with the new column definitions, populate it if required from the original table, and to then replace the original table with the new table ( a) drop original and b)rename new or a) rename original, b) rename new and c) drop original)
e.g. :-
DROP TABLE IF EXISTS original;
CREATE TABLE IF NOT EXISTS original (mycolumn INTEGER);
INSERT INTO original VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(0);
-- The original table now exists and is populated
CREATE TABLE IF NOT EXISTS newtable (mycolumn TEXT);
INSERT INTO newtable SELECT CAST(mycolumn AS TEXT) FROM original;
ALTER TABLE original RENAME TO old_original;
ALTER TABLE newtable RENAME TO original;
DROP TABLE IF EXISTS old_original;
SELECT *,typeof(mycolumn) FROM original;
The result being :-
i think the sql query statement is wrong ,try
ALTER TABLE tblUsers MODIFY COLUMN id TYPE integer USING (id::integer);
instead of id use column name....
hope this helps....
EDIT:
"ALTER TABLE tblUsers MODIFY COLUMN "+strColumnName+" TYPE integer USING ("+strColumnName+"::integer);"
I have a table in database, each record of this table needs to store
multiple Strings, i dont know how many Strings because its decided at runtime.
I want to add image uri's in database table dynamically, user
dynamically add images in my app as many as he want so i need to save
uri of them, what is the right approach to do it?
I am trying something like this by follow this Insert new column into table in sqlite ?
String ColumnName=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString() + "/" + "image1.jpg");
addNewColumn(ColumnName);
i used below method for this (not worked):-
First i am adding new column in table :-
public Cursor addColumn(String name){
db=dbhelper.getWritableDatabase();
return db.rawQuery("alter table info add column " + name + " text", null);
}
Then insert uri into this
public Boolean setUri(String columnName,String uri) {
ContentValues cv= new ContentValues();
cv.put(columnName,uri);
SQLiteDatabase db =dbhelper.getWritableDatabase();
long id=db.insert("info",null,cv);
if(id>-1)
return true;
else
return false;
}
is the above approach correct?
also i searched and fine below code :-
private static final String ALTER = "ALTER TABLE user_table ADD user_street1 TEXT";
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL(ALTER);
}
can i call onUpgrade() method dynamically and add new column or any other way to do it..?
Thanks in advance :)
It's very bad to have an arbitrary number of columns in a table. You should instead use a second table with a foreign key referencing the ID of a row in the first table.
table user
_id username ...
------------------------
1 abc
2 xyz
table photoInfo
userId photoUri
-------------------------------
1 /path/to/image1.jpg
1 /path/to/image2.jpg
2 /path/to/image3.jpg
1 /path/to/image4.jpg
To show photos for a particular user, use a JOIN.
i have create one Database and add some columns in that DB.now i need some columns added in the existing db with a new columns but without overlapping the exsisting table values.
i have face some error for adding new tables with exsisting table values
Use standard SQL in a two-step process to insert new rows and update existing rows. The following is one way to do it, but it’s not the best way:
insert into t1 (a, b, c)
select l.d, l.e, l.f
from t2 as l
left outer join t1 as r on l.d = r.a
where r.a is null;
update t1 as l
inner join t2 as r on l.a = r.d
set l.b = r.e, l.c = r.f;
You can use ALTER TABLE in your onUpgrade() method
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//add new coloumn and change your database version to an increased new value
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE TABLE_NAME ADD COLUMN NEW_COLOUMN_NAME TEXT NOT NULL");
}
}
Try following query
INSERT INTO new_table(col1, col2, col3....) SELECT col1, col2, col3.... FROM existing_table
So, I already have my app on playstore....
Now, I want to add a column to the database in my app. For this, I must upgrade my databse which can be done by changing the database version.
The users will already have some stuff in the database and when I will upload the updated version of my app (with changed version of the databse), it will create a new databse and user will loose all the stuff he/she has in his/her database.
What is the solution for this issue? And how to backup / restore contents of the old databse to new database? (I know how to backup the database by simply copy pasting the database to external storage programatically).
You can use onUpgrade() method for handling this.
Something like this:
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion == 1 && newVersion == 2) {
db.execSQL("create temporary table people_tmp ("
+ "id integer, name text, position text, posid integer);");
db.execSQL("insert into people_tmp select id, name, position, posid from people;");
db.execSQL("drop table people;");
db.execSQL("create table people ("
+ "id integer primary key autoincrement,"
+ "name text, posid integer);");
db.execSQL("insert into people select id, name, posid from people_tmp;");
db.execSQL("drop table people_tmp;");
}
}
So. You are creating temporary table and saving all needed info inside that table. Next you dropping your table, creating new one and inserting values to it from your temporary table. You can add additional fields and feel free to put there all what you want.
UPDATE:
After a little googling i found an easier solution:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// If you need to add a column
if (newVersion == 2) {
db.execSQL("ALTER TABLE foo ADD COLUMN new_column INTEGER DEFAULT 0");
}
}
Alter table method will change your database structure without loosing data.
If you are only adding a new column, you can alter existing table instead of create new table. An example:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(oldVersion<2){
db.execSQL("ALTER TABLE "+this.getTableName()+" ADD COLUMN "+COLUMNS.NAME+ " integer default 0;", null);
db.execSQL("UPDATE "+this.getTableName()+ " SET "+COLUMNS.NAME+ "="+COLUMNS.NAMEVALUE+";", null);
}
};
Here is Android documentation on ALTER TABLE use case in onUpgrade(). So in this case, if you are not rename or remove existing table, you don't need to backup old table.
If you add new columns you can use ALTER TABLE to insert them into a
live table.
Also see: https://stackoverflow.com/a/8291718/2777098
Im writing application on Android and im using SQlite database.
I want to be able to add columns to my table by the user choice.
so the user can add any column that he wants the to table. For example the user have "animal" table and he want to add column for "dog", "cat" and "fish".
I have read about some solutions and i didnt saw one that can help me.
I read that the simple way to add column is using:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// If you need to add a column
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE " + TableName + " ADD COLUMN " + ColumnName);
}
}
But my problem with this that i cant choose what is the name of the column that will be added to the table by the user choise, there is no parameter for string.
So i tried using something like this, and to call it directly.
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion, String newColumnName) {
// If you need to add a column
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE " + TableName + " ADD COLUMN " + newColumnName);
}
}
But i got error for this method.
I have another question about the database version.
The onUpgrade method get automaticly called when onCreate get called.
In onUpgrade there is oldVersion and newVersion parameters for the database version. when do i set the oldVersion and newVersion parameters? How i set my newVersion parameter to 2,3,4...?
You can create an auxiliary table to hold the extra column data. Queries to your primary table can be converted into queries on a new view.
create table if not exists animal (pk integer primary key, name);
create table if not exists animal_aux (animal_pk, col_name, col_val);
create view if not exists animal_view
as select animal.name as name,
ct.col_val as cat,
dt.col_val as dog
from animal, animal_aux as ct, animal_aux as dt
where animal.pk = ct.animal_pk
and animal.pk = dt.animal_pk
and ct.col_name = 'cat'
and dt.col_name = 'dog'
;
This schema should be enhanced to make animal_pk, col_name a primary key, or at least unique in animal_aux. You may also need triggers to add or remove entries in the aux table when you insert or delete entries in the animal table.
Example:
sqlite> select * from animal_view;
sqlite> insert into animal values (NULL, 'fred');
sqlite> select * from animal_view;
sqlite> select * from animal;
1|fred
sqlite> insert into animal_aux values (1, "dog", "beagle");
sqlite> insert into animal_aux values (1, "cat", "siamese");
sqlite> select * from animal_view;
fred|siamese|beagle
sqlite>
Each time you add a virtual column, you'll need to
drop view animal_view;
and then re-create it with the appropriate extra columns and where clauses.
final static String Database_name="empDb.db";
public DatabaseHelper(Context context) {
super(context, Database_name, null, 1);
}
#Override public void onCreate(SQLiteDatabase db) {
db.execSQL("create table emp_tbl (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,salary TEXT)");
}
#Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS tbl_emp");
}
blog: https://itmulc.blogspot.com/2016/08/android-sqlite-database-with-complete.html
Get more info about it.
https://www.youtube.com/watch?v=W8-Z85oPNmQ