Get information from SQLite (Android Studio) - java

I am new in Android Studio and I just started to work with the SQLite
I created a SQLite file (db) and I created a function that put some data in the table:
public String FirstInsert()
{
String meassage = new String();
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COL_2,"hi how are you?");
cv.put(COL_3,"blabla");
cv.put(COL_4,"blabla");
cv.put(COL_5,"blabla");
cv.put(COL_6,"blabla");
cv.put(COL_7,"blabla");
cv.put(COL_8,"blabla");
cv.put(COL_9,"blabla");
cv.put(COL_10,"blabla");
cv.put(COL_11,"blabla");
long result = db.insert(TABLE_NAME,null,cv);
if(result == -1)
{
meassage = new String("Bad");
}
else
{
meassage = new String("Good");
}
return meassage;
}
I want the do more spesific select that take only one item, the COL_2 and the row is number that I get so I wrote this code:
public Cursor GetQuestions(int num)
{
//num++;
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("SELECT QUESTION FROM " + TABLE_NAME + "ORDER BY " + num + "ASC LIMIT 1",null);
return res;
}
this is the right code? and if it is why I got an error here too?
Thank you very much for trying to help!

yes,that's because not having space between words of sqlite code
and it's better to close your cursor and your db after every query
like this
res.close();
db.close();

I just saw that i had to do space in the SQLite code like this:
Cursor res = db.rawQuery("SELECT QUESTION FROM " + TABLE_NAME + "**&**ORDER BY " + num + "**&**ASC LIMIT 1",null);
& = space (I write & to show where I added the spaces.

Related

How to check if row exists or not before insertion?

I want to insert records to my sqllite database but before insertion i have to check if the record exists .
I used this code but still say no such column and stopped working although the record exists .
SQLiteDatabase db = this.getReadableDatabase();
String selectQuery = "SELECT * FROM " + TABLE_TEAM + " WHERE "
+ TEAM_TABLE_NAME + " = " + name+";";
Log.e(LOG, selectQuery);
Cursor c = db.rawQuery(selectQuery, null);
if (c != null) {
return true;
}
return false;
This is the recommended way to use rawQuery():
String selectQuery = "SELECT * FROM " + TABLE_TEAM + " WHERE " + TEAM_TABLE_NAME + " = ?";
Cursor c = db.rawQuery(selectQuery, new String[] {name});
so you pass name as a parameter to the query and avoid the risk of sql injection.
In your code you only check if the Cursor object is null and not if it contains any rows which is the right thing to do.
So return the result of getCount() > 0 like this:
return c.getCount() > 0;
This will return true if the name already exists in the table.
As for the no such column error, this is something different.
First make sure that TEAM_TABLE_NAME is the correct name of the column and if it is then maybe you made changes to the names of the columns tha are not reflected to the database.
So uninstall the app from the device so the database is deleted and then rerun to recreate the database with the new names of the columns.

Cursor is empty but query is (supposedly) right

I've got very strange problem.
My snippet is looking like that
public Wynik getData(int pomiar, int godzina) {
Wynik wynik = null;
String query = "SELECT * FROM " + "insulina" + " WHERE godzina = " + godzina +
" AND cukier = " + pomiar;
SQLiteDatabase db = this.getReadableDatabase();
try (Cursor cursor = db.rawQuery(query, null)) {
Log.i("tag", "cursor length:" + cursor.getCount());
if (cursor.getCount() > 0) {
String s = DatabaseUtils.dumpCursorToString(cursor);
Log.d("s", s);
cursor.moveToFirst();
wynik = new Wynik
(cursor.getInt(cursor.getColumnIndexOrThrow("godzina")),
cursor.getString(cursor.getColumnIndexOrThrow("insulina")),
cursor.getInt(cursor.getColumnIndexOrThrow("dawka")),
cursor.getString(cursor.getColumnIndexOrThrow("cialo")));
}
cursor.close();
return wynik;
(sorry for not English convention, but it was meant to be quick, routinely project)
Whole app idea is to help my friend with his grandmother's diabetes. He would insert an result of blood sugar level test (cukier) and time of test is checked automatically (godzina).
Based on those, app should return a whole result (wynik), with required dose of insulin (dawka), type of it (insulina) and part of body from which the blood should be taken (cialo).
Database looks like this:
So for example. The blood result is 10 (it's only thing which user is inserting) and it's 7 P.M (19, by 24-hours convention - the program is giving the closest hour of test, so it's 18). So, the query looks like
SELECT * FROM insulina WHERE godzina = 18 AND cukier = 10
And here's my problem. The app is recognizing cursor length as 0 (it should be 1) even if my other app related to database creation (DB Browser for SQLite) is giving out my result properly with the same query
Also Android Studio says that database is sucessfully opened.
I cannot find a fault here. And I'm really confused with this problem.
I think the query should be :
String query = "SELECT * FROM insulina WHERE godzina = ? AND cukier = ?";
SQLiteDatabase db = this.getReadableDatabase();
try (Cursor cursor = db.rawQuery(query, new String[]{String.valueOf(godzina), String.valueOf(pomiar)})) {
//... rest of code
Also looks like you're using "try with resources" so the close isn't explicitly necessary.

Retrieving row data from SQLite Db based on Unique Identifier

I have implemented an SQLite DB into my app and i am trying to write functions that will retrieve the data in a row associated with the unique identifier. I have tried a lot of stackoverflow answers and none seem to be working in my situation.
I have a database helper class where i have created the database through code and am writing the functions. See code below:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "TrackerNew.db";
public static final String TABLE_NAME = "tracker_new_table";
public static final String COL_2 = "LINETYPE";
public static final String COL_3 = "PACKAGETYPE";
public static final String COL_4 = "QUANTITY";
public static final String COL_5 = "DURATION";
public static final String COL_6 = "STARTTIME";
public static final String COL_7 = "ENDTIME";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1); }
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TABLE_NAME +" (LINETYPE TEXT PRIMARY KEY,PACKAGETYPE TEXT,QUANTITY TEXT,DURATION TEXT,STARTTIME TEXT,ENDTIME TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
public boolean insertData(String linetype, String packagetype, String quantity, String duration, String starttime, String endtime) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_2,linetype);
contentValues.put(COL_3,packagetype);
contentValues.put(COL_4,quantity);
contentValues.put(COL_5,duration);
contentValues.put(COL_6,starttime);
contentValues.put(COL_7,endtime);
long result = db.insert(TABLE_NAME,null,contentValues);
if(result == -1)
return false;
else
return true;
}
//FUNCTIONS TO GET DATA BY ROW
public Cursor getAllData() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select * from "+TABLE_NAME,null);
return res;
}
public Cursor getProgressBar1() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.query("select * from "+ TABLE_NAME + "where" + COL_2="S1");
return res;
}
public Cursor getProgressBar2() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.query("select * from "+ TABLE_NAME + "where" + COL_2="S2");
return res;
}
}
If you can see my functions at the bottom of my code i am trying to write raw queries to get the data by ID( S1,S2 Etc.)
Can anyone help me out with the code inside these functions?
Thanks!
The issue is that you are trying to create a string using:-
"select * from "+ TABLE_NAME + "where" + COL_2="S1"
This will not compile because you have misplaced the = and overwritten or omitted the + concatenation. I believe that you should have (see later):-
"select * from "+ TABLE_NAME + "where" + COL_2 + "=S1"
(+ added after COL_2 and = moved inside the quotes.
However I then believe that this would fail because you have omitted spaces before and after where, so the above would then resolve to:-
select * from tracker_new_tablewhereLINETYPE = S1
With spaces around where as per :-
"select * from "+ TABLE_NAME + " where " + COL_2 + "=S1"
It will then resolve to :-
select * from tracker_new_table where LINETYPE=S1
However, SQLite will then fail as S1 is not numeric and thus must be in quotes, so you need to actually code :-
"select * from "+ TABLE_NAME + " where " + COL_2 + "='S1'"
However coding :-
public Cursor getProgressBar1() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.query("select * from "+ TABLE_NAME + "where" + COL_2="S1");
return res;
}
Will then fail as the Cursor query method expects at least 7 parameters, as per :-
query(String table, String[] columns, String selection, String[]
selectionArgs, String groupBy, String having, String orderBy)
Query the given table, returning a Cursor over the result set.
SQLiteDatabase
So to use the query method the parameters would be:-
1) The name of the table to be queried so db.query(TABLE_NAME ......
2) A string array of the column names to extract, null means all and equates to *, so db.query(TABLE_NAME,null ......
3) The selection string (SELECT clause) (which can include placeholders i.e ? as per 4th parameter). Without place holders db.query(TABLE_NAME,null,COL_2 + "='S1'", or with a placeholder (generally considered the preferred method), db.query(TABLE_NAME,null,COL_2 + "=?" ......
4) The values to replace the placeholder(s) on a use once basis. So for a single place holder new String[]{"S1"} could be used, so the code now becomes db.query(TABLE_NAME,null,COL_2 + "=?",new String[]{"S1"} ......
5) A GROUP BY clause, null if not using one.
6) A HAVING clause, null if not using one.
7) An ORDER BY clause, null it not using one.
(Note clauses do not have the respective KEYWORDS the query method inserts them it also handles escaping/quoting)
The full query could/should be:-
Cursor res = db.query(TABLE_NAME,null,COL_2 + "=?",new String[]{"S1"},null,null,null);
Finally
And the ProgressBar1 method would be:-
public Cursor getProgressBar1() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.query(TABLE_NAME,null,COL_2 + "=?",new String[]{"S1"},null,null,null);
return res;
}
Edit after comment
As you want to also search for "S2" and "S3" then perhaps a single method could cope e.g.
public Cursor getProgressBar(String linetype) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.query(TABLE_NAME,null,COL_2 + "=?",new String[]{linetype},null,null,null);
return res;
}
Then for progress bar 1 you could use:-
Cursor progressbar1 = getProgressbar("S1");
for progress bar 2
Cursor progressbar2 = getProgressbar("S2");
etc
You could also shorten the getProgressBar method to :-
public Cursor getProgressBar(String linetype) {
SQLiteDatabase db = this.getWritableDatabase();
return db.query(TABLE_NAME,null,COL_2 + "=?",new String[]{linetype},null,null,null);
}
or even :-
public Cursor getProgressBar(String linetype) {
return this.getWritableDatabase().query(TABLE_NAME,null,COL_2 + "=?",new String[]{linetype},null,null,null);
}
Just try to modify this query:
Cursor res = db.query("select * from "+ TABLE_NAME + "where" + COL_2="S1");
to:
Cursor res = db.rawQuery("select * from "+ TABLE_NAME + " where " + COL_2 + " = ?", new String[] {"S1"});
and in getProgressBar2() method too. For more info look to https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

Update multiple rows based on id in sqlite on android?

I have db table as follows
I want to update status column to 1 with id = 1,2,3.
For a single row I can update with content values
public void updateJobStatus(int callId) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues data = new ContentValues();
data.put(AppDBConstants.KEY_JOB_DETAIL_STATUS, 1);
db.update(AppDBConstants.TABLE_JOB_DETAIL, data, AppDBConstants.KEY_JOB_DETAIL_CALL_ID + "=" + callId, null);
db.close();
}
What to do for multiple rows?
Update Your query like this
db.update(AppDBConstants.TABLE_JOB_DETAIL, data, AppDBConstants.KEY_JOB_DETAIL_CALL_ID + " IN (?,?,?)", new String[]{"1","2","3"});
I think you current code is working for multiple id but need some of changes as below to achieve your requirement :
public void updateJobStatus(int[] callIds) {
SQLiteDatabase db = this.getWritableDatabase();
if (db != null) {
db.beginTransaction();
try {
for(int id : callIds){
ContentValues data = new ContentValues();
data.put(AppDBConstants.KEY_JOB_DETAIL_STATUS, 1);
db.update(AppDBConstants.TABLE_JOB_DETAIL, data, AppDBConstants.KEY_JOB_DETAIL_CALL_ID + "=" + id, null);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
db.close();
}
}
Note : As above you need to pass id array it might be one or multiple.
When you have unknown number of arguments, try this one
String args = TextUtils.join(", ", arrayOfIds);
db.execSQL(String.format("UPDATE %s SET %s = true WHERE %s IN (%s);",
TABLE_INCOMING_MESSAGES, KEY_MESSAGE_SENT, KEY_ID, args));

SQLite, return data as an array

I have an SQLite Database in my android application with the following structure:
public void onCreate(SQLiteDatabase db) {
String CREATE_LISTS_TABLE = "CREATE TABLE " + TABLE_LISTS +
"("+
_ID + " INTEGER PRIMARY KEY , " +
NOTE + " TEXT" +
")";
db.execSQL(CREATE_LISTS_TABLE);
}
And this works, in that I can insert data into it without a problem. However I need to store the notes inside an array. I currently have the following query:
public List<String> getAllNotes() {
List<String> notes = new ArrayList<>();
String GET_ALL_NOTES = "SELECT * FROM " + TABLE_LISTS;
SQLiteDatabase db = getReadableDatabase();
if(db!=null)
{
Cursor cursor = db.rawQuery(GET_ALL_NOTES, null);
cursor.moveToFirst();
while(!cursor.isAfterLast())
{
notes.add(String.valueOf(cursor.getInt(cursor.getColumnIndex("notes"))));
cursor.moveToNext();
}
cursor.close();
}
db.close();
return notes;
}
However, this gives the following error:
java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
I was wondering how to fix this, I have read the android developer stuff but I can't seem to get anything to work.
Thanks in advance
Check the value of "NOTE", and use it in:
notes.add(String.valueOf(cursor.getInt(cursor.getColumnIndex(NOTE))));
I think a best way to make the call should be something like this:
// Check the cursor
if(cursor != null) {
if (cursor.moveToFirst()) {
// Variables to be used
String note;
// Col position
int colNote = cursor.getColumnIndex(NOTE);
do {
// Get the information
note = cursor.getString(colNote);
// Add the note
notes.add(note);
} while (cursor.moveToNext());
}
// Close the cursor
cursor.close();
}
Because you are fetching only integer and string from database, instead of using ArrayList , you can try using HashMap. So you can get the value by just giving the key. Below simple code will work for ArrayList too with minor changes..
Try this
HashMap<Integer,String> notes = new HashMap<Integer,String>() ;
Cursor cursor = db.rawQuery(GET_ALL_NOTES, null);
while (cursor.moveToNext())
{
int i = cursor.getInt(0);
String s = cursor.getString(1);
notes.put (i,s) ;
}
cursor.close();

Categories