How to Fetch data from database by passing two numbers as parameters? - android

i want to get some data from my database by passing 2 values like
getdata("1","5");
My function in database and the id is stored as String in database.
getdata(String FromMember_id,String ToMember_id){
}
I have also cast the id to get data but I didnt get data
Query is
"SELECT * FROM MilkCollection WHERE cast(member_code as REAL)
BETWEEN '"+ FromMember_id + "' AND '" +ToMember_id+ "' ";
When is use this Query without casting
"SELECT * FROM MilkCollection WHERE member_code '"+ FromMember_id + "'
AND '" + ToMember_id + "'"
and when i dont cast the member_code and do the same query it shows data but it shows the other data other id like 17,18,19 i guess its taking the starting value of 17,18,19 because there is 1 in starting of them.

As i understand your issue, you need to type cast your passing values to REAL which sure gives you a workaround solutions.
"SELECT * FROM MilkCollection WHERE cast(member_code as REAL) >='"+ FromMember_id + "' AND cast(member_code as REAL) <= '" + ToMember_id + "' ";
Description: Just because you are passing string values using your member function which causes uncertainty while fetching data from your database.

Here is some working code for sending objects for a get. You can compare and see where you have taken a misstep.
public String getPreachLogString(long day, String time) {
String selectQuery;
SQLiteDatabase db;
Cursor cursor;
String myPath = DATABASE_PATH + DATABASE_NAME;
db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
selectQuery = "SELECT * FROM TABLE WHERE day = " + day + " AND time = \"" + time + "\"";
cursor = db.rawQuery(selectQuery, null);
To use strings in search I wrap string in \" where you wrap in '. Not sure why you are storing member IDs as string, assuming you have letters involved, but try casting member_code as TEXT to make a logical comparison between the 2 objects.
What you are trying to accomplish is possible I do it all the time. You just need to compare properly.
public ArrayList<String> getMonthlyWork(int year, int month) {
long thismonth = 0;
long nextmonth = 0;
String selectQuery;
SQLiteDatabase db;
ArrayList<String> result = new ArrayList<>();
SimpleDateFormat formatDate = new SimpleDateFormat("dd-MM-yyyy", Locale.US);
String myPath = DATABASE_PATH + DATABASE_NAME;
Calendar c = Calendar.getInstance();
c.set(year, month, 1);
thismonth = c.getTimeInMillis();
if (month < 11) {
c.set(Calendar.MONTH, month + 1);
} else {
c.set(Calendar.MONTH, 0);
c.set(Calendar.YEAR, year + 1);
}
nextmonth = c.getTimeInMillis();
db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
selectQuery = "SELECT * FROM TABLE WHERE day >= " + thismonth + " AND day < " + nextmonth;

Seems like John Bravdo already given you a working example
Let me address following 2 areas:
1. Why following SQL is not returning result?
Code:
"SELECT * FROM MilkCollection WHERE cast(member_code as REAL)
BETWEEN '"+ FromMember_id + "' AND '" +ToMember_id+ "' ";
With parameter value:
SELECT * FROM MilkCollection WHERE cast(member_code as REAL)
BETWEEN 1 AND 5;
Answer: Your table does not has any record containing value 1 to 5, but it does has record with value 17, 18, 19. Try pass the value 17 and 19 instead of 1 and 5, then it should return value. Moreover, test the SQL in database directly to confirm it does return data before checking in your program
Poor performance
Using a function call on any indexed column, e.g. cast(member_code as REAL), will not able to make use of index (regular index). Therefore, this SQL going to scan the entire table. You will start to see poor performance as the table size grow. Therefore, you need to use a column that is integer type in order to filter by integer value. You can add this column later after you have bandwidth. If the table is just a 1MB in disk, then you need to consider how many concurrent users are going to trigger this SQL call. If there are 1000 users running it concurrently, then it will cause 1GB of disk I/O (although DB engine could cache it) and it will be slow as well

Related

SQLite Statement in Android Studio 3.5.3

I'm a newbie with Android Studio so please be patient... This forum often leads me with suggestions and examples (as a reader), but today I decided to ask for help:
Since hours, I try to build an SQLite statement in Android Studio: There is a column COLUMN_LAST_ATTEMPT with date and time as String, e.g. 2020-01-09 17:23, see screenshot, and I want to get the newest date (without time) from the table, e.g. 2020-09-01. I tried various options but I can't get it to run.
What I need is an Android SQLite Statement for
SELECT MAX(SUBSTR(last_attempt,11,20)) FROM quiz_questions
(which runs on DBBrowser), where 'last attempt' is a column of table 'quiz_questions', screenshot of that column in table 'quiz_questions'
I tried the following rawQueries, none of them works:
In QuizDBHelper-Class
//...
final QuizDbHelper dbHelper = QuizDbHelper.getInstance(this);
//...
public String newestQuiz(){
db = getReadableDatabase();
String result = null;
Cursor cursor = db.rawQuery("SELECT MAX(" + QuizContract.QuestionsTable.COLUMN_LAST_ATTEMPT + ") FROM "
+ QuizContract.QuestionsTable.TABLE_NAME, null);
//Cursor cursor = db.rawQuery("SELECT MAX(SUBSTR(" + QuizContract.QuestionsTable.COLUMN_LAST_ATTEMPT +
// ",11,20)) FROM " + QuizContract.QuestionsTable.TABLE_NAME, null);
//Cursor cursor = db.rawQuery("SELECT " + QuizContract.QuestionsTable.COLUMN_LAST_ATTEMPT + " FROM " +
// QuizContract.QuestionsTable.TABLE_NAME, null);
if(cursor.moveToFirst()){
do {
result = cursor.getString(c.getColumnIndex(QuizContract.QuestionsTable.COLUMN_LAST_ATTEMPT));
} while (cursor.moveToNext());
}
cursor.close();
return result;
}
In Statistics-Class
String LastUse = dbHelper.newestQuiz();
LastUsage.setText("Letzte Challenge: " + LastUse);
//LastUsage is a TextView in activity_Statistics.xml
//attached with LastUsage = findViewById(R.id.text_lastUsage);
Either the SQLite statements are totally wrong or I make (basic?) mistakes in statistics class. I need ...newbie help!
I need something like Select column from table where substring of date-Entry == newest
Your issue appear to be column names. That is a Cursor only contains the columns extracted, not all the columns from the table. Although you are basing your query on the column as per QuizContract.QuestionsTable.COLUMN_LAST_ATTEMPT that will not be the column name in the cursor.
Rather it will will MAX(SUBSTR(" + QuizContract.QuestionsTable.COLUMN_LAST_ATTEMPT +
// ",11,20))
The simplest way of managing this is to give the column in the Cursor a specific name using AS. As such perhaps use :-
Cursor cursor = db.rawQuery("SELECT MAX(" + QuizContract.QuestionsTable.COLUMN_LAST_ATTEMPT + ") AS " + QuizContract.QuestionsTable.COLUMN_LAST_ATTEMPT + " FROM "
+ QuizContract.QuestionsTable.TABLE_NAME, null);
However, you may prefere to use a column name (AS ????) specififc to the situation e.g.
........ AS max_" + QuizContract.QuestionsTable.COLUMN_LAST_ATTEMPT + ........
You would then have to use :-
result = cursor.getString(c.getColumnIndex("max_" + QuizContract.QuestionsTable.COLUMN_LAST_ATTEMPT));
Alternately, as it's just a single value/column that is returned in the cursor you could use the column offset of 0, in which case the column name is irrelevant as long as it is valid. However, using offsets is not typically recommended due to the lack of validation of the column being accessed.
re the comment :-
I just need the date part
As the date is a recognised DateTime format (and also that such formats are directly sortable/orderable), use max(date(column_name)) or even max(column_name).

How to efficiently query sqlite database multiple times on Android

For my application, I need to query a sqlite database around 40-50 times. I am sure that the code I wrote is very inefficient. Unfortunately, I cannot find many examples online that involves querying the database many times.
String[] entryValArray = new String[indicesList.size()];
DBHelper dbHelper = new DBHelper(MainActivity.context);
SQLiteDatabase db = dbHelper.getReadableDatabase();
for (int i = 0; i < indicesList.size(); i++) {
int moddedIndex = Integer.parseInt(indicesList.get(i), 16) % DBHelper.numEntries;
String queryStr = "select * from " + DBHelper.TBL_NAME + " where " + DBHelper.IDStr +
" = " + Integer.toString(moddedIndex);
Cursor cursor = db.rawQuery(queryStr, null);
if (cursor.moveToFirst())
entryValArray[i] = cursor.getString(1);
cursor.close();
}
Basically, I am taking a list of strings, converting them to hex values, and then modding the value to get an index into a sqlite database. This is for a password generator application.
Is there a better way to do this, especially regarding creating a cursor and then closing it in every iteration.
First of all you have to change your query string as you need only one column value but you are using
Select *
instead of
Select yourColumn
. Secondly if your indices list size is not very large you can use
IN(values ) function of db instead of
" where " + DBHelper.IDStr +" = " + Integer.toString(moddedIndex);
this will return the result in only one query you don't have to run a whole loop.

Date in database changes to the current date

I am saving the data with the date it was filed, but the date I inset changes to the current date
When you save the data
Calendar currentDate=Calendar.getInstance();
DatabaseOperations DB = new DatabaseOperations(ctx);
DB.putInformation(DB, done_today1 + "\n" + done_today2 + "\n" + done_today3, thankful_for1 + "\n" + thankful_for2 + "\n" + thankful_for3 + "\n" + thankful_for4 + "\n" + thankful_for5, for_relationship, for_kids, for_business, currentDate.get(Calendar.DATE) + "-" + currentDate.get(Calendar.MONTH) + "-" + currentDate.get(Calendar.YEAR));
Inserts the data into the table
public void putInformation(DatabaseOperations dop,String happenedToday,String thankfulFor,String forRelationship,String forKids,String forBusiness,String currentDate){
SQLiteDatabase SQ=dop.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put(TableData.TableInfo.DONE_TODAY, happenedToday);
cv.put(TableData.TableInfo.THANKFUL_FOR,thankfulFor);
cv.put(TableData.TableInfo.FOR_RELATIONSHIP,forRelationship);
cv.put(TableData.TableInfo.FOR_KIDS,forKids);
cv.put(TableData.TableInfo.FOR_BUSINESS,forBusiness);
cv.put(TableData.TableInfo.CURRENT_DATE,currentDate);
SQ.insert(TableData.TableInfo.TABLE_NAME, null, cv);
Log.d("Database operations", "One Row Inserted");
And when I retrieve the date this way
Cursor CR = dop.getInformation(dop);
CR.moveToFirst();
Toast.makeText(DisplayTable.this,""+CR.getString(5),Toast.LENGTH_LONG).show();
I am getting the current date and not the date that the data was filed in.
Any one knows why is it happening?
In SQL, CURRENT_DATE is a keyword that refers to the current date.
To access a column with the same name, you have to quote the column name (double quotes are for identifiers; single quotes are for strings):
> CREATE TABLE t(current_date);
> INSERT INTO t VALUES('x');
> SELECT current_date FROM t;
2015-09-28
> SELECT "current_date" FROM t;
x
> SELECT 'current_date' FROM t;
current_date
It might be a better idea to use a different column name.
Best way to handle date and times is to always use ISO standard timestamps, the ones with T and Z. This makes translating actual dates within different time zones easy.
One way also is saving date and times using unix timestamp, its a long integer that can be translated to the actual dates of different time zones, so it will reflect always the correct time based on your time zone.

deleting records from sqlite on the basis of date in android

I want to delete some records from android's database where two conditions are fulfilled.
1. there's a column with the name as sync_status, it should have a value 'C' and
2. there's column which has date.
Now I want to delete only those rows where sync_status is = 'c' and date is less than device's current date. I'm having problem in comparing the device's current date with the date stored in the database and my function deletes all the records.
public int RemoveSyncData(){
DBHelper = new DatabaseHelper(context);
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy ");
Calendar calObj = Calendar.getInstance();
String currentDate = dateFormat.format(calObj.getTime());
Log.e("current date",currentDate);
int rows = db.delete(DATABASE_TABLE_DAILY_ATTENDANCE, KEY_ATTENDANCE_SYN_STATUS + "= ? and " + KEY_ATTENDANCE_DATE_ONLY + " != '" + currentDate + "'", new String[] {"C"});
db.close();
return rows;
}
If you absolutely want to keep the date as a string in the form MM-DD-YYYY in your database column, then the only way to do comparison of those dates is to convert them to seconds using SQLite's strftime function. However, in order to do that, you have to restructure the date as YYYY-MM-DD because your current format is not one that can be used as input to the date and time functions of SQLite.
Here is a sample:
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");
Calendar calObj = Calendar.getInstance();
String currentDate = dateFormat.format(calObj.getTime());
String where = KEY_ATTENDANCE_SYN_STATUS + " = ?1 AND "
+ "STRFTIME('%s', SUBSTR(" + KEY_ATTENDANCE_DATE_ONLY + ",7) "
+ "|| '-' || SUBSTR(" + KEY_ATTENDANCE_DATE_ONLY + ",1,5)) < "
+ "STRFTIME('%s', SUBSTR(?2,7) || '-' || SUBSTR(?2,1,5))";
String[] whereArgs = {"C", currentDate};
int rows = db.delete(DATABASE_TABLE_DAILY_ATTENDANCE, where, whereArgs);
If you use yyyy-MM-dd when creating currentDate, you can replace the second instance of the ugly substring + concatenation with just STRFTIME('%s', ?2), but you will still need the first substring + concatenation to transform the column values in the table.
If it's not too late for you to change how your database stores the date, make your life easier by either storing as yyyy-MM-dd (to get rid of all the substring + concatenation above), or better yet store the long date and only worry about converting it to and from MM-dd-yyyy at the java layer.
** EDIT **
Your condition is right it should delete only the rows that meet the condition, just tested it on my SQLite Viewer with some dummy data..
Just be 100% sure that your variable names match the column names and also check the database, if there are some rows which shouldn't be deleted. Maybe there is no entry for today's date and "C" is present in all rows thats why all the records are being deleted.
You can also try the "not so good way":
db.execSQL("delete FROM tableName WHERE KEY_ATTENDANCE_SYN_STATUS = 'C' AND KEY_ATTENDANCE_DATE_ONLY != '"+currentDate+"'");
The above is not a good way as execSQL won't return anything so you won't have anyway to know if it was successful except for checking it yourself.
The above approach is only to test your condition though.

SQL Between operation in android sqlite date is not working?

I am new to android development. I been working on this for one day and i couldn't figure out whats the exact problem is because my query is running without error but no result.
My database query Value of formattedDate
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = df.format(c.getTime());
public Cursor paymentWeek(Activity activity)
{
String[] from = { _PAYMENTID, NAME, REQUESTEDDATE, FROMAD, TOADD, EMAILBODYPAYMENT, AMOUNT};
SQLiteDatabase db = getReadableDatabase();
String orderby = REQUESTEDDATE+" DESC";
Cursor cursor = db.rawQuery("SELECT * FROM " + PAYMENTTABLE+ " WHERE " + REQUESTEDDATE + " BETWEEN date('"+formattedDate+"') AND date('"+formattedDate+"','-7 days')", null);
activity.startManagingCursor(cursor);
return cursor;
}
My database date type is TEXT. i am storing in the format of (yyyy-mm-dd),eg:2012-04-07
But the problem is i can retrieve all datas from the database but if i want to retrieve values for last 7 days it doesn't show any values.
It would be great if any alternatives available? and tip how to go for it?
Thanks...
Cursor cursor = db.rawQuery("SELECT * FROM " + PAYMENTTABLE+ " WHERE " + REQUESTEDDATE + " BETWEEN date('"+formattedDate+"') AND date('"+formattedDate+"-7')", null);
Try out this query, you have made a mistake in date('"+formattedDate+"','-7 days')".
as you say, your date type is TEXT, i dont think you can use between x and y to make the filter to return the content from x to y .
you can try this: http://www.roseindia.net/sql/sql-between-date.shtml or http://www.techonthenet.com/sql/between.php .

Categories

Resources