I am creating a database based application which requires to search through the database in a specific column for a name and then list all entries which are filtered by the keyword.
For example
Database entries:
1 Test 123 chicken
If someone searches chicken, it will output or direct towards the entry 1.
you need to use WHERE clause along with your SELECT statement,
SELECT *
FROM tableName
WHERE name = 'chicken'
String arg = "chicken";
String query = "select * from table_name where title=\""+ arg + "\"";
Cursor cs = mSqlDB.rawQuery(query, null);
You should have your selected row in cursor cs.
Imagine that you have a button and you click it...Try it:
Button saveButton = (Button) findViewById(R.id.search_button);
saveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
String searchStr = search.getText().toString(); // Here is "chicken"
Cursor c = sampleDB.rawQuery("SELECT Id, Name, Price FROM "+SAMPLE_TABLE_NAME+" WHERE Name like '"+searchStr+"'", null);
if (c != null ) {
if (c.moveToFirst()) {
do {
int idNumber = c.getInt(c.getColumnIndex("Id"));
Log.v("IdNumber", id);
}while (c.moveToNext());
}
}
}
});
Related
I have to make more than 300 selects from my database.
Each of those queries has to be called inside of a for each loop, here's an example:
for(int id : myids){
Cursor cursor = MyDatabaseHelper.runMyQuery(id);
while(cursor.moveToNext()){
//my stuff...
}
}
MyDatabaseHelper is an instance of a database helper class, the function is like this
public Cursor runMyQuery(int id){
SQLiteDatabase db = this.getWritableDatabase();
Cursor ret = db.rawQuery("select Name, Surname, Age from PTable where Id = " + id, null);
return ret;
}
I've been told that the constant "open and close" of the db because of multiple queries it the cause of my performance issues and I should, instead, make a single query (using union etc).
Changing my code to a single query would mean changing the entire database, and I was hoping not to do that.
Is there anything I can do to improve the performance and keep the multiple selects at the same time?
Thanks
I think what you are looking for is the in clause.
Convert your myids into a string. Something like
String inClause = "(1,2,3)"
and you can use it as
"select Name, Surname, Age from PTable where Id in " + inClause
You can read more of the in operator here
You can return a single Cursor containing all the rows.
First change your runMyQuery() method to this:
public Cursor runAll(String list){
SQLiteDatabase db = this.getWritableDatabase();
String sql = "select Name, Surname, Age from PTable where " + list + " like '%,' || id || ',%'"
Cursor ret = db.rawQuery(sql, null);
return ret;
}
So you pass to the method runAll() a String which is the the comma separated list of all the ids that you have in myids and with th eoperator LIKE you compare it to each id of the table.
You create this list and get the results in a Cursor object like this:
StringBuilder sb = new StringBuilder(",");
for(int id : myids){
sb.append(String.valueOf(id)).append(",");
}
String list = sb.length() > 1 ? sb.toString() : "";
if (list.length() > 0) {
Cursor c = runAll(list);
while(c.moveToNext()){
//your stuff...
}
}
I tried to calculate a report and displays the result in the texview "edt1". But it's not displayed.
there is mydatabasehelper :
public void calculrapport(Argent a)
{
db = this.getWritableDatabase();
String query = "select sum(Entree) from Argent where date between \"datedebut\" and \"datefin\" ;";
Cursor cursor = db.rawQuery(query , null) ;
int count = cursor.getCount();
}
There is my class Rapport.java :
public void onOKClick ( View v ) {
if (v.getId() == R.id.okrapport) {
EditText datedebut = (EditText) findViewById(R.id.datedebut);
EditText datefin = (EditText) findViewById(R.id.datefin);
String strdatedebut = datedebut.getText().toString();
String strdatefin = datefin.getText().toString();
Argent a = new Argent();
helper.calculrapport(a);
edt1.setText( );
}
}
Thanks in advance.
Assuming that the query works as expected (especially considering that variables used have the appropriate scope, which would appear unlikely perhaps try using select sum(Entree) from Argent to test without the complications of wheteher or not the datedebut and datefin variables can resolve and if so resolve to usable values) then you need to :-
Extract the appropriate value and return the value from the method and then use the returned value to set the text in the TextView.
To return the value the method should not be void, but have an appropriate return type (String will be used for the example),
so instead of public void calculrapport(Argent a), use public String calculrapport(Argent a) (thus the method will be required to return a string)
To extract the value the cursor needs to be moved to the appropriate row (there should only be the one row as the sum function is an aggregate function and there is only the one group (aggregate functions work on gropus) i.e. all rows)
As such the method could be :-
public String calculrapport(Argent a)
{
String rv = "0"; //<<<< used to return 0 if no rows are selected by the query
db = this.getWritableDatabase();
String query = "select sum(Entree) from Argent where date between \"datedebut\" and \"datefin\" ;";
Cursor cursor = db.rawQuery(query , null) ;
if (cursor.moveToFirst()) {
rv = cursor.getString(0); //<<<< get the value from the 1st (only) column
}
cursor.close(); //<<<< Cursors should always be closed when done with
return rv;
}
To set the TextView with the returned value instead of using :-
helper.calculrapport(a);
edt1.setText( );
Use :-
edt1.setText(helper.calculrapport(a));
Or :-
String sum = helper.calculrapport(a);
edt1.setText(sum);
Additional re comment:-
The problem is located in the SQlite query (select sum(Entree) from
Argent where date between \"datedebut\" and \"datefin\" ;) exactly
when we call "datedebut" and "datefin" taht located in the class
rapport.java
Then String query = "select sum(Entree) from Argent where date between \"datedebut\" and \"datefin\" ;";
resolves to :-
select sum(Entree) from Argent where date between "datedebut" and "datefin" ;
I believe, assuming that datedebut and datefin are string variables, and that they are in a valid SQLite date format e.g. they could be 2018-01-01 and 2018-02-01 (and that values in the date column are formatted as a valid SQLite date format) that you should instead be using :-
String query = "select sum(Entree) from Argent where date between '" + datedebut + "' and '" + datefin +"' ;";
Which would then resolve to something like :-
SELECT sum(entree) FROM argent WHERE date BETWEEN '2018-01-01' AND '2018-02-01';
For valid SQLite date formats; refer to Date And Time Functions
Note the above is in-principle code and has not been tested so may contain some simple typing errors.
Anyoneee Pliss Help, I Want To Show A Data From Database, But When I Run It Say's Error Outofboundsexception, Can Anyone Help Me? The Error Sign In Below
public ArrayList<Sma> getPoint(String name)
{
ArrayList <Sma> point = new ArrayList<Sma>();
String selectQuery = "SELECT latitude_sma, longtitude_sma FROM sma WHERE nama_sma ='" + name + "'"; >> FROM HERE I JUST WANT TO SHOW latitude_sma, and longtitude_sma IN A TEXTVIEW
open();
Cursor c = database.rawQuery(selectQuery, null);
if (c.moveToFirst()) {
do {
Sma sekolah = new Sma();
sekolah.setLatitude(c.getString(c.getColumnIndex(latitude_sma)));
sekolah.setLongitude(c.getString(c.getColumnIndex(longtitude_sma)));
point.add(sekolah);
}
while (c.moveToNext());
}
return point;
}
And here is my Activity
private void handleIntent(Intent intent)
{
if (Intent.ACTION_SEARCH.equals(intent.getAction()))
{
dataSource.open();
String query = intent.getStringExtra(SearchManager.QUERY);
DBDataSource dataSource = new DBDataSource(this);
ArrayList<Sma> list = dataSource.getPoint(query);
TextView tv = (TextView) findViewById(R.id.txtQuery);
//WHEN I RUN THIS CODE BELOW, THE ERROR HAPPEND > IndexOutOfBounds
tv.setText(list.get(0).getLongitude().toString());
tv.setText(list.get(1).getLatitude().toString());
}
}
Can Anyone Help Me, Please, Thanks B4 :D
The problem is the way you are handling your cursor. You will eventually be trying to read column data beyond the last row of the cursor. Use the following idioms instead. (You are also not closing the cursor, which is a separate problem also taken care of by this sample.)
ArrayList <Sma> point = new ArrayList<Sma>();
Cursor cursor = null;
try {
cursor = database.rawQuery(...);
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
Sma sekolah = new Sma();
sekolah.setLatitude(cursor.getString(cursor.getColumnIndex(latitude_sma)));
sekolah.setLongitude(cursor.getString(cursor.getColumnIndex(longtitude_sma)));
points.add(sekolah);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return points;
You have simply no sure that you have two elements in your list.
try to check before you try to list.get(0) or list.get(1) it.
ArrayList<Sma> list = dataSource.getPoint(query);
if(list.size()>2){
TextView tv = (TextView) findViewById(R.id.txtQuery);
//WHEN I RUN THIS CODE BELOW, THE ERROR HAPPEND > IndexOutOfBounds
tv.setText(list.get(0).getLongitude().toString());
tv.setText(list.get(1).getLatitude().toString());
}
You can also think about changing your sql statement to sth like this
Cursor c = db.rawQuery("SELECT latitude_sma, longtitude_sma FROM sma WHERE nama_sma = ?", new String[] {name});
to check your data in sqlite db please follow it
# Switch to the data directory
cd /data/data
# Our application
cd de.vogella.android.todos
# Switch to the database dir
cd databases
# Check the content
ls
# Assuming that there is a todotable file
# connect to this table
sqlite3 yourDBName.db
here is my code:
public String getFriendName(int aFindexnum){
String sql = "SELECT * FROM peopleTable WHERE "+KEY_CBINDEX+"="+aFindexnum;
Cursor cursor = ourDatabase2.rawQuery(sql, null);
String Fname = cursor.getString(1);
cursor.close();
return Fname;
}
I am trying to search for an integer and than return other Value that is String in my sqldatabase
So i am passing in that aFindexnum which is the integer value in the Db and i want to find it
my problem was when i tried to do something like that:
public String getFriendName(int aFindexnum){
String aFindex = getString(aFindexnum);
String sql = "SELECT * FROM peopleTable WHERE "+KEY_CBINDEX+"=?";
Cursor cursor = ourDatabase2.rawQuery(sql, new String[] {aFindex});
String Fname = cursor.getString(1);
cursor.close();
return Fname;
}
String aFindex = getString(aFindexnum); <<if i will turn this with
parse into String will it work ?
public long createEntry( String name, String phonenum ,int phoneindex) {
// TODO Auto-generated method stub
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, name);
cv.put(KEY_PHONENUM, phonenum);
cv.put(KEY_CBINDEX, phoneindex);
return ourDatabase2.insert(DATABASE_TABLE, null, cv);
}
this is the entry of the sql Db, so u can see in the third column i am putting an int and i want to search for it and get the name and the phone.
thanks.
getString() in an activity gets a string from resources. Referring to a resource id with the name of an index number looks suspicious. If I understood your code and question, this
Cursor cursor = ourDatabase2.rawQuery(sql, new String[] {aFindex});
should be
Cursor cursor = ourDatabase2.rawQuery(sql, new String[] { String.valueOf(aFindexnum) });
and you can remove the first problematic getString().
When you query and get a Cursor, you'll have to move it to a valid row before accessing column data. Add
if (cursor.moveToFirst()) { ... }
If I understood your code and question,
By reading your sql String code you want row which matches KEY_CBINDEX value
If in your database data type of KEY_CBINDEX column is int then you can get integer value
By replacing
cursor.getString(1);
with
int intValue = cursor.getInt(cursor.getColumnIndex(KEY_CBINDEX));
or if is string, then replace with
int intValue = Integer.parseInt(cursor.getString(cursor.getColumnIndex(KEY_CBINDEX)));
You have to replace it in your second code block.
In My Application, I am going to store name of all the available tables from my database with this code:
public ArrayList<Object> showAllTable()
{
ArrayList<Object> tableList = new ArrayList<Object>();
String SQL_GET_ALL_TABLES = "SELECT name FROM sqlite_master WHERE type='table'";
Cursor cursor = db.rawQuery(SQL_GET_ALL_TABLES, null);
cursor.moveToFirst();
if (!cursor.isAfterLast())
{
do
{
if(cursor.getString(0).equals("android_metadata"))
{
//System.out.println("Get Metadata");
continue;
}
else
{
tableList.add(cursor.getString(0));
}
}
while (cursor.moveToNext());
}
cursor.close();
return tableList;
}
Yes i am able to store it. But while i am going to display it in to ListView, it will display in such way that last created shown at last. I want to display the list of the table as Last created, display first in to ListView.
Please help me, What should I have to do in my code to set such way of displaying tables?
There are several ways to do it. The easiest is probably to change your SQL call by adding ORDER BY. Here's something you can try out:
To order the items ascending:
String SQL_GET_ALL_TABLES = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name ASC";
Or descending:
String SQL_GET_ALL_TABLES = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name DESC";
Alternative solution
Another option would be to do it like you're doing it right now, and instead go through the Cursor from the last to the first item. Here's some pseudo code:
if (cursor.moveToLast()) {
while (cursor.moveToPrevious()) {
// Add the Cursor data to your ArrayList
}
}
before return the values just call the method
Collections.reverse(tableList);
see the full code
public ArrayList<Object> showAllTable()
{
ArrayList tableList = new ArrayList();
String SQL_GET_ALL_TABLES = "SELECT name FROM sqlite_master WHERE type='table'";
Cursor cursor = db.rawQuery(SQL_GET_ALL_TABLES, null);
cursor.moveToFirst();
if (!cursor.isAfterLast())
{
do
{
if(cursor.getString(0).equals("android_metadata"))
{
//System.out.println("Get Metadata");
continue;
}
else
{
tableList.add(cursor.getString(0));
}
}
while (cursor.moveToNext());
}
cursor.close();
Collections.reverse(tableList);
return tableList;
}