How can i store columns dynamically in SQLite database in android? - android

I am new in Android development.Please help me How can i store columns name in Sqlite database dynamically.
Create database below here:
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(
"create table contacts " +
"(id integer primary key, name text,phone text,email text, street text,place text)"
);
}
And insert query below here:
public boolean insertContact (String name, String phone, String email,String street,String place)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name", name);
contentValues.put("phone", phone);
contentValues.put("email", email);
contentValues.put("street", street);
contentValues.put("place", place);
db.insert("contacts", null, contentValues);
return true;
}

you can use ALTER TABLE function on your onUpgrade() method, like this :
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// If you need to add a column
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE foo ADD COLUMN new_column INTEGER DEFAULT 0");
}
}
Obviously, the SQLite will differ depending on the column definition

You do not need to provide a value for every column in your table to insert a new row. You can just change the code in your method to:
public long insertContact(ContentValues contentValues) {
return db.insert("contacts", null, contentValues);
}
Let the calling function decide which values it wants to insert, which can be all, some or none of the available columns. Any values not specified will be null in the table. For example if calling function does:
EditText name, email;
// ...
ContentValues values = new ContentValues();
values.put("name", name.getText().toString());
values.put("email", email.getText().toString());
insertContact(values);
will insert a new row in the database with "name" and "email" filled in and the rest of the columns null.

Related

How to get PRIMARY KEY ID of objects in DataBase -android sqlite 3

I want to get a primary key of a saved object in a table in database I wrote a class to handle my database I want to add a function to it for getting the Id (I tried to give id to objects manually it didn't go well so I prefer the primary key id)so how should this function look like?and also if u see a thing that needs changing in my code please let me know.
public class DataBaseHandler extends SQLiteOpenHelper {
private static int _ID =0;
private int ID =0;
private ArrayList<marker_model> markerList=new ArrayList<>();
public DataBaseHandler(Context context) {
super(context, Constans.TABLE_NAME, null, Constans.DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+Constans.TABLE_NAME+
" ("+Constans.MARKER_ID+" INTEGER PRIMARY KEY, "+
Constans.MARKER_TITLE+" TEXT, " +Constans.MARKER_DESCRIPTION+" TEXT ,"+Constans.My_MARKER_ID+" INT );");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+Constans.TABLE_NAME);
onCreate(db);
}
public void AddMarker(marker_model marker){
marker.set_Id(_ID);
SQLiteDatabase db=this.getWritableDatabase();
ContentValues values=new ContentValues();
values.put(Constans.MARKER_TITLE,marker.getTitle());
values.put(Constans.My_MARKER_ID,marker.get_Id());
values.put(Constans.MARKER_DESCRIPTION,marker.getDescription());
db.insert(Constans.TABLE_NAME,null,values);
db.close();
Log.d(TAG, "AddMarker: Successfully added to DB");
_ID++;
}
public ArrayList<marker_model> getMarkers(){
markerList.clear();
SQLiteDatabase db =getReadableDatabase();
Cursor cursor=db.query(Constans.TABLE_NAME
,new String[]{Constans.My_MARKER_ID,Constans.MARKER_TITLE,
Constans.MARKER_DESCRIPTION},null,null,null,null,null);
if (cursor.moveToFirst()){
do {
ID=0;
marker_model model=new marker_model();
model.set_Id(_ID);
model.setDescription(cursor.getString(cursor.getColumnIndex(Constans.MARKER_DESCRIPTION)));
model.setTitle(cursor.getString(cursor.getColumnIndex(Constans.MARKER_TITLE)));
markerList.add(model);
ID++;
}while(cursor.moveToNext());
}
cursor.close();
db.close();
return markerList;
}
public int getMarkerPrimaryId(Marker marker){
}
}
Assuming that you want to get the _id (the primary key) from the database and that marker is an instance of a marker_model object AND that
marker_model has methods getTitle and getDescription that return a string with the respective values, then something along the lines of the following would work.
public long getMarkerPrimaryId(Marker marker){
long rv = 0;
SQLiteDatabase db = getReadableDatabase();
String[] columns = new String[]{Constans.My_MARKER_ID};
String whereclause = Constans.MARKER_TITLE + "=?" +
Constans.MARKER_DESCRIPTION + "=?";
String[] whereargs = new String[]{
marker.getTitile,
marker.getDescription
}
Cursor cursor = db.query(Constans.TABLE_NAME,
columns,
whereclause,
whereargs,
null,null,null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
rv = cursor.getLong(cursor.getColumnIndex(Constans.My_MARKER_ID);
}
cursor.close;
db.close;
return rv;
}
However, if your issue is that getMarkers is not setting the Id member appropriately (i.e. to match the id in the database), then changing model.set_Id(_ID);
to
model.set_Id(cursor.getLong(cursor.getColumnIndex(Constans.My_MARKER_ID));
would suffice.
If your expectation is that an automatically generated incrementing _id is to be used the addMarker is a little flawed. Simply by removing the line values.put(Constans.My_MARKER_ID,marker.get_Id()); will result in _id being automatically generated (which how _id's tend to be used).
The following (BACKGROUND paragraph mostly) explains much about automatically generated unique identifiers (even though it is about AUTOINCREMENT you likely DO NOT want to code AUTOINCREMENT).
Id suggest that rather than :-
if (cursor.moveToFirst()){
do {
...
}while(cursor.moveToNext());
using :-
while (cursor.moveToNext() {
....
}
is simpler (a cursor, when created, will be positioned to before the first row (moveToPosition(-1) has the same effect) , moveToNext() will move to the first row the first time, if there are no rows the loop will not be entered (you may wish to consider this and the state of returned markerlist)).
Note! the above has been written without testing, so there may be the odd mistake.

set foreign key in android sqlite

I have these two tables in my android app: 'account' and 'person' .
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("create table account "
+ "(accountId integer primary key autoincrement,bank_name text,hesab_num text unique,cart_num text unique,cvv2 text,expire_date date , pId integer)");
db.execSQL("create table person (personId integer primary key autoincrement,name text)");
}
.
account:
ACCOUNT_COLUMN_BANK
ACCOUNT_COLUMN_HESAB
ACCOUNT_COLUMN_CART
ACCOUNT_COLUMN_CVV2
ACCOUNT_COLUMN_EXPIRE_DATE
ACCOUNT_COLUMN_P_ID // foreign key for person
person:
PERSON_COLUMN_NAME
and i have this method in android dbHelper class:
public boolean insertAccount(Person person, Bank bank) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues bankValues = new ContentValues();
ContentValues personValues = new ContentValues();
personValues.put(PERSON_COLUMN_NAME, person.getName());
long id = db.insert(PERSON_TABLE_NAME, null, personValues); // get id of person
bankValues.put(ACCOUNT_COLUMN_BANK, bank.getBankName());
bankValues.put(ACCOUNT_COLUMN_HESAB, bank.getAccountNumber());
bankValues.put(ACCOUNT_COLUMN_CART, bank.getCardNumber());
bankValues.put(ACCOUNT_COLUMN_CVV2, bank.getCvv2());
bankValues.put(ACCOUNT_COLUMN_EXPIRE_DATE, bank.getExpireDate()
.toString());
bankValues.put(ACCOUNT_COLUMN_P_ID, (int) id); // set id of person in account table
db.insert(ACCOUNT_TABLE_NAME, null, bankValues);
return true;
}
most of the times that i call this method , foreign key in account table is null. why? and what i must do ?
point: foreign key can be Repetitious , because a person can have many account.

Can't stop table from autoincrement id when insert unique field

I have a table with 2 columns, a numeric id and unique text. Created like this:
String CREATE_MY_TABLE = "CREATE TABLE " + TABLE_TEST + "("
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ KEY_FOO + " TEXT UNIQUE"
+ ")";
db.execSQL(CREATE_MY_TABLE);
I want that when I insert KEY_FOO value and it's already in the db, nothing happens. But what I get is that the id is always incremented. No new row is inserted, that's good, but the id is autoincremented.
What I'm doing to insert is as follows:
db.insertWithOnConflict(TABLE_TEST , null, values, SQLiteDatabase.CONFLICT_NONE);
I tried CONFLICT_IGNORE, CONFLICT_ABORT, CONFLICT_ROLLBACK, all the same.
The reason I need this is because other table has a foreign key on this id, thus if the id is changed, the other table points nowhere.
How I just say to let the existing entry untouched?
Try this way. In your dbhelper class write the method like following to insert.
public int insertData(String desc) {
db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
try {
db.beginTransaction();
cv.put(KEY_FOO, desc);
db.insertOrThrow(TABLE_TEST, null, cv);
db.setTransactionSuccessful();
} catch (Exception ex) {
return 1;
} finally {
db.endTransaction();
db.close();
}
return 0;
}
Then from your actvity you call this method with the parameter value of KEY_FOO. This method will return 1 if the exception is occurs (If you try insert a unique value) and it will return 0 if the transaction is successfull.
I hope this way will help you. Let me know if any problem.

Android SQLite Upgrade without losing data

I have created a SQLite database successfully and it works fine. However when the onUpgrade method is called, I'd like to do so without losing data. The app I'm developing is a quiz app. Simply, when the onCreate method is called I create and prepopulate a database with questions, answers etc. The last column is whether they have set the question as a favourite or not. What I would like to do is that when the onUpgrade method is called, I'd like to temporarily save that one column, drop the whole database, recreate it with any edits I've made to old questions and add any new questions then re-add back the questions that they set as favourites.
So one option I tried was the following:
db.execSQL("ALTER TABLE quiz RENAME TO temp_quiz");
onCreate(db);
db.execSQL("INSERT INTO quiz (favouries) SELECT favourites FROM temp_quiz");
db.execSQL("DROP TABLE IF EXISTS temp_quiz");
However this doesn't work owing to the fact INSERT INTO just adds new rows rather than replacing the existing rows. I have also tried REPLACE INTO, INSERT OR REPLACE INTO and
db.execSQL("INSERT INTO quiz (_id, favouries) SELECT _id, favourites FROM temp_quiz");
of which none work.
Currently I do have it set up to work by altering the name of the table, calling the onCreate(db) method and then setting up a cursor which reads each row and uses the db.update() method as shown below:
int place = 1;
int TOTAL_NUMBER_OF_ROWS = 500;
while (place < TOTAL_NUMBER_OF_ROWS) {
String[] columns = new String[] { "_id", ..........., "FAVOURITES" };
// not included all the middle columns
Cursor c = db.query("temp_quiz", columns, "_id=" + place, null, null, null, null);
c.moveToFirst();
String s = c.getString(10);
// gets the value from the FAVOURITES column
ContentValues values = new ContentValues();
values.put(KEY_FLAG, s);
String where = KEY_ROWID + "=" + place;
db.update(DATABASE_TABLE, values, where, null);
place++;
c.close();
}
However whilst this works it is extremely slow and will only get worse as my number of questions increases. Is there a quick way to do all this?
Thank you! P.S. Ideally it should only update the row if the row is present. So if in an upgrade I decide to remove a question, it should take this into account and not add a new row if the row doesn't contain any other data. It might be easier to get it to remove rows that don't have question data rather than prevent them being added.
changed it to:
db.execSQL("UPDATE new_quiz SET favourites = ( SELECT old_quiz.favourites
FROM old_quiz WHERE new_quiz._id = old_quiz._id) WHERE EXISTS
( SELECT old_quiz.favourites FROM old_quiz WHERE new_quiz._id = old_quiz._id)");
Which works :D
public class DataHelper extends SQLiteOpenHelper {
private static final String dbName="dbName";
private Context context;
private SQLiteDatabase db;
private final static int version = 1;
public static final String SurveyTbl = "CREATE TABLE SurveyTbl (SurveyId TEXT PRIMARY KEY, Idref TEXT, SurveyDate TEXT)";
public DataHelper(Context context) {
super(context, dbName, null, version);
this.db = getWritableDatabase();
this.context = context;
Log.i("", "********************DatabaseHelper(Context context)");
}
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(SurveyTbl);
} catch (Exception e) {
Log.i("", "*******************onCreate");
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
db.execSQL("ALTER TABLE HandpumpSurveyTbl ADD COLUMN NalYozna TEXT");
} catch (Exception e) {
Log.i("", ""+e);
}
onCreate(db);
}
}
I didn't get to see your Quiz table schema, but I assume it has fields like "question", "answer", "favorites", and some kind of a unique primary key to identify each question, which I will just call rowId for now.
// after renaming the old table and adding the new table
db.execSQL("UPDATE new_quiz SET new_quiz.favorites = old_quiz.favorites where new_quiz.rowId = old_quiz.rowId");
That will update only the rows of the new quiz table that match the old quiz table, and set the favorites value from the old quiz table.
I assume you have some kind of a unique identifier to identify each question, so instead of the rowId above, you'll use that (question number or something).
For who don't know yet how to upgrade the version of the SQLite when upgrading the database schema for example, use the method needUpgrade(int newVersion)!
My code:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
if(newVersion>oldVersion){
db.execSQL(scriptUpdate);
db.needUpgrade(newVersion);
}
}
ALTER TABLE mytable ADD COLUMN mycolumn TEXT
In your onUpgrade method, it would look something like this:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String upgradeQuery = "ALTER TABLE mytable ADD COLUMN mycolumn TEXT";
if (newVersion>oldVersion)
db.execSQL(upgradeQuery);
}
Example, how to drop a table and create a new table without losing data by using a temporary table:
db.execSQL("CREATE TEMPORARY TABLE temp_table (_id INTEGER PRIMARY KEY AUTOINCREMENT, col_1 TEXT, col_2 TEXT);");
db.execSQL("INSERT INTO temp_table SELECT _id, col_1, col_2 FROM old_table");
db.execSQL("CREATE TABLE new_table (_id INTEGER PRIMARY KEY AUTOINCREMENT, col_1 TEXT, col_2 TEXT, col_3 TEXT);");
db.execSQL("INSERT INTO new_table SELECT _id, col_1, col_2, null FROM temp_table");
db.execSQL("DROP TABLE old_table");
db.execSQL("DROP TABLE temp_table");

How to view a data in table

I inserted EditText value in database, Please help me how to get all the data in table and show it in a next Activity, please help me. I use the following code for inserting:
private static final String DATABASE_CREATE = "create table pill (id integer primary key autoincrement, "
+ "med VARCHAR, " + "dose1 VARCHAR,"+"dose2 VARCHAR,"+"dose3 VARCHAR);";
// ---insert data into the database---
public long insertData(String med, String dose1,String dose2,String dose3) {
ContentValues initialValues = new ContentValues();
initialValues.put(Med, med);
initialValues.put(Dose1, dose1);
initialValues.put(Dose2, dose2);
initialValues.put(Dose3, dose3);
return db.insert(DATABASE_TABLE, null, initialValues);
}
med, dose1, dose2, dose3 are the values from the EditText which is in another class.
You have to use:
db.query()
See that
Query only the first data from a table

Categories

Resources