Fetching SQLite Data Using Order By DateTime But Not Work - java

I want to Get All data (Date and time wise) but it's not helpful for me AND also Don't Show any error
Follow this Below links But It's Not Helpful For Me :
android sqlite orderby datetime always fetches 1st row
Order By datetime column SQLite
Why is the ORDER BY not working in a Sqlite query
Insert Record in to SQLite database :
private String getDateTime() {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm a");
Date date = new Date();
return dateFormat.format(date);
}
public long insertCompany(Company company){
//String sql = null;
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DatabaseHelper.KEY_COMPANY_NAME, company.getName());
values.put(DatabaseHelper.KEY_CREATED_AT, getDateTime());
values.put(DatabaseHelper.KEY_COMPANY_WEBSITE,company.getWebsite());
values.put(DatabaseHelper.KEY_COMPANY_EMAIL,company.getEmail());
values.put(DatabaseHelper.KEY_COMPANY_PHONE_HOME,company.getPhoneHome());
values.put(DatabaseHelper.KEY_COMPANY_PHONE_PRIMARY,company.getPhonePrimary());
values.put(DatabaseHelper.KEY_COMPANY_ADDRESS,company.getAddressLine1());
long company_id = db.insert(COMPANY, null, values);
return company_id;
}
Below Code is i'll implement in my Database but It's can't work :
List<Company> companyList = new ArrayList<Company>();
String selectQuery = "SELECT * FROM " + COMPANY + " ORDER BY (" + KEY_CREATED_AT + ") ";
Log.e(TAG, selectQuery);
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, null);
Full Code :
public List<Company> getAllCompany(){
List<Company> companyList = new ArrayList<Company>();
String selectQuery = "SELECT * FROM " + COMPANY + " ORDER BY (" + KEY_CREATED_AT + ") ";
Log.e(TAG, selectQuery);
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, null);
if (c.moveToFirst()) {
do {
Company com = new Company();
com.setId(c.getInt(c.getColumnIndex(KEY_ID)));
com.setName(c.getString(c.getColumnIndex(KEY_COMPANY_NAME)));
com.setWebsite(c.getString(c.getColumnIndex(KEY_COMPANY_WEBSITE)));
com.setEmail(c.getString(c.getColumnIndex(KEY_COMPANY_EMAIL)));
com.setPhoneHome(c.getString(c.getColumnIndex(KEY_COMPANY_PHONE_HOME)));
com.setPhonePrimary(c.getString(c.getColumnIndex(KEY_COMPANY_PHONE_PRIMARY)));
com.setAddressLine1(c.getString(c.getColumnIndex(KEY_COMPANY_ADDRESS)));
com.setDate(c.getString(c.getColumnIndex(KEY_CREATED_AT)));
//com.setDate(c.getString(c.getColumnIndex(KEY_UPDATED_AT)));
companyList.add(com);
} while (c.moveToNext());
}
return companyList;
}
See Below Image For Batter understanding Data was not show in Date and Time wise :
Help me :)
Thanks in Advance

VARCHAR not working for date while sorting data. You can insert milliseconds in database and format date while show in View.
replace this line in insertCompany Method.
values.put(DatabaseHelper.KEY_CREATED_AT, System.currentTimeMillis());
replace this line while getting data from DB.
long time = Long.parseLong(c.getString(c.getColumnIndex(KEY_CREATED_AT)));
com.setDate(getFromatDate(time));
Method for format data from Milliseconds.
public String getFromatDate(long dateTime) {
String formatedDate;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(dateTime);
Date mDate = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm a", new Locale("en"));
formatedDate = sdf.format(mDate);
return formatedDate;
}
also u can add DESC at end of your Query See below code:
String selectQuery = "SELECT * FROM " + COMPANY + " ORDER BY (" + KEY_CREATED_AT + ") DESC " ;

Here is full implementation example.
If KEY_CREATED_AT is a char or varchar and not a date otherwise you can simply use order by clause that would be fine.
You can use CONVERT to change the values to a date and sort by that
SELECT *
FROM
COMPANY
ORDER BY
CONVERT(DateTime, KEY_CREATED_AT ,101) DESC
The problem with that is, as Sparky points out in the comments, if KEY_CREATED_AT has a value that can't be converted to a date the query won't execute.
This means you should either exclude the bad rows or let the bad rows go to the bottom of the results
To exclude the bad rows just add WHERE IsDate(KEY_CREATED_AT ) = 1
To let let the bad dates go to the bottom you need to use CASE
e.g.
ORDER BY
CASE
WHEN IsDate(KEY_CREATED_AT) = 1 THEN CONVERT(DateTime,KEY_CREATED_AT,101)
ELSE null
END DESC

You are missing the 'order' to your query in order by clause
String selectQuery = "SELECT * FROM " + COMPANY + " ORDER BY (" + KEY_CREATED_AT + " DESC)";
You can use either ASC or DESC as per required behavior.

Related

How to SELECT * FROM table WHERE month AND year in SQLite database by rawQuery(query, args)?

I was trying to select all the columns in the table where the "month" and "year" are the same.
The method rawQuery(query,args) receive an array of string[] with the a query that replaces the camps with "?".
This was some of my attempts:
"SELECT * FROM EXPENSES WHERE strftime('%m', EXPENSE_DATE)=" + month + " AND strftime('%y',EXPENSE_DATE) =" + year;
and
"SELECT * FROM EXPENSES WHERE strftime('%Y/%m', 'EXPENSE_DATE') =" + year + "/" + month;
and the last with the "?" replacing the args with the method in question:
String[] selectionArgs = new String[]{String.valueOf(year), String.valueOf(month)};
Cursor cursor = database.rawQuery("SELECT * FROM expenses WHERE expense_date >='?-?-01' AND expense_date <='?-?-31'", selectionArgs);
In the end after the problem appear again, i discovered that the problem was that the Object of the view was giving one DATE and the system was giving another format.
Basically i have a CALENDARVIEW that was giving me the data format of ("00-0-00") and if the variable was null the program would get the system date which was giving me the date format ("00-00-00")
The code to fill the null date was this:
//Get the default TIMEZONE
calendar = Calendar.getInstance();
//Set the format date
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
date = simpleDateFormat.format(calendar.getTime());
and the CALENDARVIEW was this:
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
#Override
public void onSelectedDayChange(#NonNull CalendarView view, int year, int month, int dayOfMonth) {
date = year + "-" + (month + 1) + "-" + dayOfMonth;//the Time will be blanck
}
});
The solution was:
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
#Override
public void onSelectedDayChange(#NonNull CalendarView view, int year, int month, int dayOfMonth) {
// the date was being save as 00-0-00 instead of 00-00-00
if (month >10) {
date = year + "-" + (month + 1) + "-" + dayOfMonth;//the Time will be blanck
}else {
date = year + "-0" + (month + 1) + "-" + dayOfMonth;//the Time will be blanck
}
}
});
and for the database in android just worked with strf:
String[] selectionArgs = new String[]{String.valueOf(year), String.valueOf(month)};
String sql = "SELECT * FROM EXPENSES WHERE "+
"strftime('%Y', EXPENSE_DATE) = ? AND strftime('%m', EXPENSE_DATE) + 0 = ? + 0";
Cursor c = db.rawQuery(sql, selectionArgs);
THAT'S IT THANKS FOR THE HELP GUYS!
Always use ? placeholders in the sql statement and pass the parameters as an array in the 2nd argument of rawQuery().
This is the recommended and safe way to do it.
I assume that the variables year and month are integers, this is why you use String.valueOf() to convert them to strings inside the string array.
I also assume that the column EXPENSES has the correct format YYYY-MM-DD so that strftime() will succeed to extract the year and the month.
The problem is that when you extract the month with strftime() it is returned as a string: a number left padded with a 0 if needed, say 05.
But if the value of month that you pass is 1-digit integer, say 5, the condition in the WHERE clause will become:
WHERE '05' = '5'
which returns false.
To overcome this problem you need an implicit conversion of the result of strftime() to an integer by adding 0.
For the year, since the values are always 4 digits, there is no such problem, but remember to use the '%Y' format inside strftime(), which stands for 4-digit years and not '%y' which stands for 2-digit years.
So write your code like this:
String[] selectionArgs = new String[]{String.valueOf(year), String.valueOf(month)};
String sql = "SELECT * FROM EXPENSES WHERE "+
"strftime('%Y', EXPENSE_DATE) = ? AND strftime('%m', EXPENSE_DATE) + 0 = ? + 0";
Cursor c = db.rawQuery(sql, selectionArgs);
Your first attempt is dangerous. This will open your app for a SQL injection attack. For a local database that only has one user, this probably isn't a big deal. But you should get in the habit of using bound parameters as in the second query.
The problem is that you can only use ? as a place holder for the entire value, so your query should be:
String query = "SELECT * FROM expenses WHERE expense_date >= ? AND expense_date <= ?"
Now you will need to build a date object or a formatted string to pass as the arguments:
String begin = year + "-" + month + "-01";
String end = year + "-" + month + "-31";
Finally execute the query:
String selectionArgs = new String[]{begin, end};
Cursor cursor = database.rawQuery(query, selectionArgs);
Alternatively, you can use the BETWEEN keyword here instead of two explicit inequality comparisions:
String query = "SELECT * FROM expenses WHERE expense_date BETWEN ? AND ?"

How to add a date to database date field, but only to the fields I extracted earlier

I have a sql statement that selects some of my tables with certain criteria from database and puts them in a temp file.
In the same database is a field called CreationDate and it is empty
protected int doWork() throws Exception {
String data = "";
File tempFile = File.createTempFile("Test",".txt");
Connection db_cn = currentDataSource.getDbConnection();
Statement select_stmt = db_cn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet r_set;
String str_sql = "select sap, og_id, kz, sap_order from database where status='A' and ver_status is null order by og_id, kz, sap, sap_order";
r_set = select_stmt.executeQuery(str_sql);
FileWriter fileWriter = new FileWriter(tempFile.getCanonicalPath(), true);
BufferedWriter bw = new BufferedWriter(fileWriter);
while (r_set.next()) {
String sap = r_set.getString("SAP");
String id = r_set.getString("OG_ID");
String kz = r_set.getString("KZ");
String order = r_set.getString("SAP_ORDER");
data = sap + "\t" + id "\t" + kz "\t" + order + "\n";
bw.write(data);
}
bw.close();
fileWriter.close();
r_set.close();
select_stmt.close();
return 0;
}
After the code runs it creates the temp file in which is data that I selected out of the database.
Now my question is, how could I after that my temp file is created, add a date of the creation(the date is enough, it doesnt have to contain hours and minutes of the day) to the same database to my CreationDate field
Problem is I dont know how to get started on this; My idea is to use the calendar from java.util.Calendar to determine the date
Calendar curr_day = new GregorianCalendar();
int curr_day_format = curr_day.get(Calendar.YEAR) * 10000 + (curr_day.get(Calendar.MONTH)+1) * 100 + curr_day.get(Calendar.DAY_OF_MONTH) ;
After that I dont know how I could insert that date back into the database for only the files that have been extracted to the temp txt file
String str_sql = "select sap, og_id, kz, sap_order from database where
status='A' and ver_status is null order by og_id, kz, sap, sap_order";
Replace the above string with the following:
String str_sql = "select sap, og_id, kz, sap_order, cast(sysdatetime() as date) CreateDate from database where status='A' and ver_status is null order by og_id, kz, sap, sap_order";
This would not be after the file is created but that seems arbitrary. This is a tsql solution, while the syntax is off the approach is the same, edit your query to add a date to the PL SQL call.

Getting specific data by column using sqlite database

I couldn't give a good title to the problem I'm having, but basically I have two columns Name and MaxNum string and int respectively!
I need int method that makes a query which retrieves the MaxNum for specific Name that I give in parameter!
.. so if I have this data
ID | Name | MaxNum
0 | Mike | 50
1 | John | 40
2 | Jess | 30
..when I put Jess in as parameter it will return 30 !
My method so far.. but I can't use it since it doesn't return int value !
public void maxFromName(String name){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT " + COLUMN_MAX + " FROM "+ TABLE_AZKAR+" WHERE " +COLUMN_NAME+ "=" + name ;
db.execSQL(query);
}
You have to get the result using
Cursor
String query = "SELECT " + COLUMN_MAX + " FROM "+ TABLE_AZKAR+" WHERE " +COLUMN_NAME+ "=" + name ;
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
return c.getInt(c.getColumnIndex("MaxNum"));
Update
Since you are facing the problem, I suggest you use the below query:
String query = Select MaxNum from azkar WHERE Name ='Jess';
after this use my code from Cursor c line, this will work.
Use rawQuery for getting data from SQLite. And from the cursor get integer value using getInt function.
Change your maxFromName function with the following.
public int maxFromName(String name){
SQLiteDatabase db = this.getReadableDatabase();
String query = "SELECT " + COLUMN_MAX + " FROM "+ TABLE_AZKAR+" WHERE " +COLUMN_NAME+ "= '" + name +"'" ;
Cursor c = db.rawQuery(query, null);
if(c.getCount()!=0){
c.moveToFirst();
return c.getInt(c.getColumnIndex("MaxNum"))
}
return 0;
}
In the API it says the following in the description of execSQL():
Execute a single SQL statement that is NOT a SELECT or any other SQL
statement that returns data.
Use a query method that returns a Cursor type in order to retrieve results
The easiest way to get a single value from a database is with the stringForQuery() or longForQuery() helper functions:
public long maxFromName(String name) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT "+COLUMN_MAX+" FROM "+TABLE_AZKAR+" WHERE "+COLUMN_NAME+" = ?";
return DatabaseUtils.longForQuery(db, query, new String[]{ name });
}
(To prevent string formatting problems and SQL injection attacks, always use parameters instead of inserting string values directly into the query.)
You can use rawQuery
public ArrayList<String> maxFromName(String name){
ArrayList<String> maxNums = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT " + COLUMN_MAX + " FROM "+ TABLE_AZKAR+" WHERE "
+COLUMN_NAME+ "=" + name ;
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
do { // if that kind of rows are more then one, this metod get all of them
maxNums.add(c.getInt(c.getColumnIndex("MaxNum")));
}
return maxNums;
}

Retrieve Data from Sqllite DB between Two dates android

I retrieve data between two dates some how it get correct result and some how it output empty listview when i select dates with month it work properly but when i select dates between more than one month it output empty listview below is my codes
here i declare the variable in DB class
public static final String EX_RowID = "_id";
public static final String EX_Cattype = "Ecattype";
public static final String EX_Date = "Ecdate";
public static final String EX_Price = "Ecprice";
public static final String EX_Type = "itype";
creat table statement
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE " + Food_TABLE +"(" +
EX_RowID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
EX_Cattype + " TEXT NOT NULL, " +
EX_Date + " TEXT NOT NULL," +
EX_Price + " INTEGER NOT NULL," +
EX_Type + " TEXT NOT NULL UNIQUE );"
);
}
enter data Method
public long ExEntry(String Ecatgtype, String Edate, String Eprice, String Eitype) {
// TODO Auto-generated method stub
ContentValues cv = new ContentValues();
cv.put(EX_Cattype, Ecatgtype);
cv.put(EX_Date, Edate );
cv.put(EX_Price, Eprice);
cv.put(EX_Type, Eitype);
return ourdatabase.insertOrThrow(Food_TABLE, null, cv);
}
here i access the ExEntry Method
ExMgDB Expentry = new ExMgDB(ADD_EX.this);
Expentry.open();
Expentry.ExEntry(cate, date, price, itype);
Expentry.close();
here i am facing the problem between these two dates variables
public Cursor CstmRpot(String fd, String td) {
// TODO Auto-generated method stub
String[] columns = new String[] {EX_RowID,EX_Cattype, EX_Date, EX_Price, EX_Type };
Cursor c= ourdatabase.query(Food_TABLE, columns, EX_Date + " BETWEEN '" + fd + "'
AND '" + td + "'" , null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
i access it like below
CustemRpt dbcs = new CustemRpt();
Cursor cursor = CstDB.CstmRpot(frmdate,tondate);
There are two major solutions. All solutions have in common, that the column containing the date has to be ordered somehow. If this order is destroyed your data is corrupt and your queries cannot return the expected results!
1. Save your Dates as INTEGER in your database and use a method to map Dates to a number:
A possible way is to use Date.getTime () to map Dates to numbers, but there are many others. Important is that
equal dates get the same number and
that a date that is after another date gets a bigger number.
This way ordering will be correct for sure.
To achieve this with `Java.util.Date.getTime() you only have to set the time to 0:00:00:000 if you want to store date only.
For example:
"CREATE TABLE " + Food_TABLE +"(" +
EX_RowID + "INTEGER PRIMARY KEY AUTOINCREMENT, " +
EX_Cattype + " TEXT NOT NULL, " +
EX_Date + " INTEGER NOT NULL," +
EX_Price + " INTEGER NOT NULL," +
EX_Type + " TEXT NOT NULL UNIQUE );"
private static String dateOnly(java.util.Date d) {
Calendar cal = Calendar.getInstance(); // locale-specific
cal.setTime(d);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return Long.toString(cal.getTimeInMillis());
}
public Cursor CstmRpot(java.util.Date fd, java.util.Date td) {
// TODO Auto-generated method stub
String[] columns = new String[]{EX_RowID,EX_Cattype, EX_Date, EX_Price, EX_Type };
Cursor c= ourdatabase.query(Food_TABLE, columns, EX_Date + " > " + dateOnly (fd) + " AND " + EX_Date + " < " + dateOnly(td), null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
If you don't use different timezones the dateOnly(java.util.Date d) can be optimized.
Of course you can also use JODA-time.
2. Save your Dates as TEXT
If you choose this method your queries that are comparing the date-column are going to be a bit slower, but the entries in the database are human readable which doesn't have t be the case with method 1.
TEXT-columns are ordered with BINARY by default, which means memcmp() is used to compare the values and to determine which value is greater or if the values are equal. (Remember x BETWEEN a AND b means x <= a AND x >= b.)
You can examine the work of memcmp() with this function memcmp().
To ensure you get the right results you have to ensure the following:
All date-values in your database have to have the same text length.
All date-values in your database have to be in the same Format. The bigger date-parts (year) have to be before the smaller date-parts (month).
All Parameters for date-values in queries have to follow these rules too.
A possible date-format may look like this: yyyy-MM-dd (for example 2014-02-04 or 2000-12-24).
Advices
Use android.widget.DatePicker instead of Edittext for getting dates as input.
Never use any texts you got from user inputs directly in your query, but validate them before (see sql-injection).
Read some articles about how Strings are compared.
Try SELECT * FROM "your table" WHERE date BETWEEN "from date" AND "to date";
you need to store date inform of yyyy-mm-dd and then use this method simply call getWeekData(start_date, end_date);
public Object getWeekData(String start_date, String end_date) {
if (!mDataBase.isOpen())
openDataBase();
Object data = new Object ();
// Select All Query
String query = (String) ("Select * from " + TBL_NAME
+ " where " + (COL_DATE + " between '" + start_date + "' AND '" + end_date + "'"));
Cursor cursor = mDataBase.rawQuery(query, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
//get data over here
} while (cursor.moveToNext());
}
// closing connection
cursor.close();
close();
return data;
}
we have Two solution for this question
one is we need to convert date and time into milliseconds, and take long data type in
Sqllite database and save values(converted date and time). And the write query like "SELECT
data, start_date, end_date from tablename WHERE start_date > end_date".
Second way is you need to save start and end date+time(yyy-MM-dd HH:mm:ss) in string format
in Sqllite database, and you need to query like this,
"SELECT datetime_start,datetime_end FROM tablename WHERE(( DATETIME(atetime_start) >=
DATETIME ("+"'"+entry_start_time+"'"+")" +" AND DATETIME(datetime_end) < DATETIME
("+"'"+entry_end_time+"'"+")); .

Parse Date to compare in JPQL query

I would like to parse an input date in java, and then use it in a query as a condition in a select in oracle database.
String date = "2013.11.05";
Date checkDate = new SimpleDateFormat("yyyy.MM.dd").parse(date);
String qString =
"SELECT DISTINCT T " +
"FROM T5PFArfolyamArch T " +
"WHERE T.arfTipus = :vcRateKod AND T.arfErvkezd = :checkDate AND T.araValid IN ('I','M')";
Query query = entityManager.createQuery(qString);
query.setParameter("vcRateKod", tipus);
query.setParameter("checkDate", checkDate);
But it gives 0 result, like the date is not equal or right format to select anything.
try this
query.setParameter("checkDate", checkDate, TemporalType.DATE);

Categories

Resources