retrieve data from database what next? - android

ok I just followed an instruction that I should do this to retrieve sql data from database but it just cuts to there so far I have this inside my databasehelper class.
public void getIconResource(String tblName)
{
SQLiteDatabase db = this.getReadableDatabase();
String getresource = "Select * from " + tblName;
Cursor cursor = db.rawQuery(getresource,null); //null for conditions
if(cursor.moveToFirst())
{
do
{
int resource = cursor.getInt(3);
}
while (cursor.moveToNext());
}
db.close();
}
So somehow this does is it get all the values of my tables 4th column which contains an int... how do I retrieve the value in my MainActivity and save it in an array of integers?

just add everything in a ArrayList and return the arraylist
simply call the method in your main activty
public ArrayList<Integer> getIconResource(String tblName)
{
SQLiteDatabase db = this.getReadableDatabase();
String getresource = "Select * from " + tblName;
Cursor cursor = db.rawQuery(getresource,null); //null for conditions
ArrayList data= new ArrayList<>();
if(cursor.moveToFirst())
{
do
{
int resource = cursor.getInt(3);
data.add(resource);
}
while (cursor.moveToNext());
}
db.close();
}
return data;
}

Well, as you have it, the variable resource is scoped only to the while loop. Even if it wasn't it would constantly get overwritten on each loop iteration.
Instead, you should declare a collection higher up and Add each value to it during your while loop. You could also redefine your function to return the collection if integers.
public List<int> getIconResource(String tblName)
{
SQLiteDatabase db = this.getReadableDatabase();
List<int> myVals = new List<int>();
String getresource = "Select * from " + tblName;
Cursor cursor = db.rawQuery(getresource, null); //null for conditions
if (cursor.moveToFirst())
{
do
{
myVals.Add(cursor.getInt(3));
}
while (cursor.moveToNext());
}
db.close();
return myVals;
}
Also, as a note... string concatenation of a SQL query is a recipe for disaster. Look up SQL Injection and best practices to avoid it before continuing further. It is worth the time to get into good habits early on.
EDIT / ADDENDUM
Unless you also limit your result set returned from your table query, you will be getting every record. The function you have here really has no practical use and would likely cause more problems than any benefits it may have. I would suggest, as an example of a more usable function that returns a specific IconResource based on the IconId:
public int getIconResource(int iconId)
{
SQLiteDatabase db = this.getReadableDatabase();
String getresource = "select IconResource from IconTable where IconId = ?";
PreparedStatement pstmnt = db.prepareStatement(getresource);
pstrmnt.setString(1, iconId);
ResultSet rset = db.executeQuery();
int iconResource;
if (rset.next())
iconResource = rset.getInt("IconResource");
db.close();
return iconResource;
}
Of course, the above is making assumptions of your table structure.
Using the above, in your code elsewhere, you would simply call this function with the IconId and use the output however needed:
int iconResource = getIconResource(5); // returns the IconResource for IconId = 5
The above prevents any possible SQL Injection attacks by using a parameterized query and avoiding the use of dynamic concatenated strings sent to your SQL server.

You may try out the following code:
public List<Integer> getIconResource(String tblName)
{
List<Integer> list = new ArrayList<Integer>();
list.clear();
SQLiteDatabase db = this.getReadableDatabase();
String getresource = "Select * from " + tblName;
Cursor cursor = db.rawQuery(getresource,null); //null for conditions
if(cursor.moveToFirst())
{
do
{
int resource = cursor.getInt(3);
list.add(resource);
}
while (cursor.moveToNext());
}
db.close();
return list;
}
Then call this method in MainActivity and store the List in another Integer type list.
databasehelper dbhelper;
List<Integer> newList = dbhelper.getIconResource("Your tablename");
fot(int i = 0 ; i< newList.size() ; i++){
int yourValue = newList(i);
}

Related

Sqlite how to improve performance?

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...
}
}

Android SQLite Database check if query exists?

Hi i'm still new in android and SQLite. I got activity which that can add query to my attached db file.
The problem is, i can't add data using my methods. Is there a simple methods to check if query is exists ?
Here is my DB Access
public class DBAccess {
private SQLiteOpenHelper openHelper;
private SQLiteDatabase db;
private static DBAccess instance;
Cursor c = null;
private DBAccess(Context context)
{
this.openHelper = new DatabaseOpenHelper(context);
}
public static DBAccess getInstance(Context context)
{
if(instance==null)
{
instance=new DBAccess(context);
}
return instance;
}
public void open()
{
this.db = openHelper.getWritableDatabase();
}
public void close()
{
if(db!=null)
{
this.db.close();
}
}
public void tambah(String a,String b)
{
String query= ("insert into TabelAbjad (kata,arti) values('"+a+"','"+b+"')");
db.execSQL(query);
}
public boolean checkdata(String c, String d)
{
String s;
String query= ("select kata from TabelAbjad where kata = '"+c+"' AND kata = '"+d+"'");
db.execSQL(query);
return true;
}
Here is when i try to call the methods
private void adddata()
{
DBAccess dbAccess = DBAccess.getInstance(getApplicationContext());
dbAccess.open();
String k = editkata.getText().toString().trim();
String a = editarti.getText().toString().trim();
if (dbAccess.checkdata(k,a))
{
Toast.makeText(this, "Data already exists",Toast.LENGTH_LONG).show();
dbAccess.close();
finish();
}
else
{
dbAccess.tambah(k,a);
dbAccess.close();
Toast.makeText(this, "Data Saved",Toast.LENGTH_LONG).show();
}
}
P.S : I'm call the method in button
You are missing a semicolon (;) in your query string.
Try this String query= ("select kata from TabelAbjad where kata = '"+c+"' AND kata = '"+d+"';"); for all your query strings
Your issue is that no row in the table will exist where the column kata has the value c as well as (AND) the value d it is impossible as a column can only have a single value, thus no rows would ever be extracted.
Perhaps you want to find rows that have either c OR d
in which case you could use :-
String query= ("select kata from TabelAbjad where kata = '"+c+"' OR kata = '"+d+"'");
i.e. AND has been changed to OR
Furthermore, execSQL cannot return a result, as per :-
Execute a single SQL statement that is NOT a SELECT or any other SQL
statement that returns data. execSQL
You thus need to either use the rawQuery method or the convenience query method, the latter recommended unless it's limitations mean that it cannot be used. As such you should try using something along the lines of (OR instead of AND assumed) :-
public boolean checkdata(String c, String d)
boolean rv = false;
String whereargs = "kata=? OR kata=?"; // the WHERE clause less the WHERE keyword ? for the arguments (used on a 1 for 1 basis)
String[] whereargs = new String[]{c,d}; // The arguments that will be substituted into the SQL
String[] columns = new String[]{"kata"};
Cursor csr = db.query("TabelAbjad",columns,whereclause,whereargs,null,null,null);
if (csr.getCount() > 0) {
rv = true;
}
csr.close();
return rv;
}
Although this may appear to be more complex to code it has advantages as it build the underlying SQL, it protects against SQL injection and it correctly encloses/escapes (wraps the values in single quotes etc) the values)arguments
You retrieve data (rows) into a Cursor (in this case you simply want to know if any rows matched the given criteria so getCount() is used (it returns the number of rows extracted which could be 0 if none)).
Is there a simple methods to check if query is exists ?
I believe that what you really mean is there anyway to check if the query returned any results.
As said above a query returns data via a Cursor (like a table but according to the query e.g. the Cursor above will consist of a number of rows (0 or more) with a single column named kata (i.e. the query is SELECT **kata** FROM .....) ) and thus you need to use a suitable method.
You can check/access numerous aspects/properties. Typically you'd move around the Cursor (e.g. while (your_cursor.moveToNext) {.... do things ....} can be used traverse all rows in the cursor). Cursor.
Once positioned appropriately at a row then you can use the get????(column_offset) to retrieve the data that came from the database (where column_offset is an integer with 0 representing the first column, however it is generally much wiser to retrieve the actual offset using the getColumnIndex(column_name_as_a_string method.))
So assuming that you wanted the data (String) in the first row that was extracted above into the Cursor csr then you could use :-
if (csr.moveToFirst()) {
String mykata = csr.getString(csr.getColumnIndex("kata"));
}
csr.close(); // You should always close a cursor when done with it.

Error retrieving cursor value as string

I have an SQLite-Database with four columns
ID
Name
symptoms
Medicine
My Helper class code
public Cursor getMedicine(String symptom1)
{
SQLiteDatabase db=helper.getReadableDatabase();
Cursor c = db.rawQuery("SELECT medicine FROM diseases WHERE symptoms = ?;",new String[] {symptom1});
c.moveToFirst();
return c;
}
And here is code of my activity class :
String med = "";
Disp_med_DBHelper medicalHelp = new Disp_med_DBHelper(this);
medicalHelp.open();
medicalHelp.getMedicine(Value1);
med = medicalHelp.getMedicine(Value1).toString();
t1.setText(med);
medicalHelp.close();
Where t1 is my textbox, and Value1 is the string that we need to send to database helper to query the database.
When I check output on my textbox, I get the following output
android.database.sqlire.SQLiteCursor#4174986
What should I do to get it fixed?
Method toString() returns string representation of object Cursor. You have to use method getString(int column) from Cursor class.
Something like this:
med = medicalHelp.getMedicine(Value1).getString(0);
More info: https://developer.android.com/reference/android/database/Cursor.html
use this method instead:
public String getMedicine(String symptom1) {
SQLiteDatabase db = helper.getWritableDatabase();
Cursor c = db.rawQuery("SELECT medicine FROM diseases WHERE symptoms = ?;", new String[]{symptom1});
if (c.moveToFirst()) {
return c.getString(c.getColumnIndex("medicine"));
}
return null;
}
and then in your activity:
med = medicalHelp.getMedicine(Value1)
if(med!=null){
t1.setText(med);
}
Even when the cursor contains only a single value, it still behaves as a cursor that might have multiple columns and multiple rows. So you have to go to the first row (with moveToFirst(), which might fail), and read the value from the first column (with getString(0)).
However, for this simple situation, there is a helper function that allows you to avoid having to muck around with a cursor:
public Cursor getMedicine(String symptom1) {
SQLiteDatabase db = helper.getReadableDatabase();
return DatabaseUtils.stringForQuery(db,
"SELECT medicine FROM diseases WHERE symptoms = ?;",
new String[]{ symptom1 });
}

Single value from cursor to int

I can't seem to figure out how I get the result from my select query (which should be one number) into my int min. Found different solution using Google but none worked.
I need the min value in order to check if the score that the current player has is higher than the lowest score in order to get in the highscores.
public int getMin(){
System.out.println("in getmin");
String selectQuery = "SELECT MIN(score) FROM tblscore;";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
int min = "something here to put the result in the int"
cursor.close();
db.close();
return min;
}
You could read the value through a cursor, but for single-valued queries like this, there is helper function in the DatabaseUtils class which makes things simpler:
public int getMin(){
String selectQuery = "SELECT MIN(score) FROM tblscore";
SQLiteDatabase db = this.getReadableDatabase();
try {
return (int)DatabaseUtils.longForQuery(db, selectQuery, null);
} finally {
db.close();
}
}
First you need to point the cursor to the first line:
cursor.moveToFirst();
Then you can use Cursor.getInt to get the value:
int min = cursor.getInt(0);

How to check the value already excists or not in sqlite db in android?

In my application I am saving a bill number in SQLite database. Before I add a new bill number how to check if the bill number exists in the DB.
My main class code is,
String bill_no_excist_or_not = db.billno_exist_or_not(""+et_bill_number.getText().toString());
Log.v("Bill No", ""+bill_no_excist_or_not);
My DB Code,
String billno_exist_or_not(String bill_number){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_BILL_DETAILS, new String[] { KEY_BILL_NUMBER }, KEY_BILL_NUMBER + "=?"
+ new String[] { bill_number }, null, null, null, null);
//after this i don't know how to return the values
return bill_number;
}
I don't know how to check the values which is already available or not in DB. Can any one know please help me to solve this problem.
Here is the function that helps you to find whether the value is available in database or not.
Here please replace your query with my query..
public int isUserAvailable(int userId)
{
int number = 0;
Cursor c = null;
try
{
c = db.rawQuery("select user_id from user_table where user_id = ?", new String[] {String.valueOf(userId)});
if(c.getCount() != 0)
number = c.getCount();
}
catch(Exception e) {
e.printStackTrace();
} finally {
if(c!=null) c.close();
}
return number;
}
Make your KEY_BILL_NUMBER column in your table UNIQUE and you can just insert using insertWithOnConflict with the flag SQLiteDatabase.CONFLICT_IGNORE

Categories

Resources