I'm currently writing an app which allows you to pick a category, and the app will retrieve all results in that category and print them onto the screen. The code for the creation of the database is fine, but I am unsure on whether my retrieval method is correct, and then totally unsure as to how I would print out the individual names of the results into a TextView.
Currently, I have:
public Cursor getDatabase(int category)
{
String myPath = DB_PATH + DB_NAME;
myData = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
Cursor cur;
cur=myData.rawQuery("select * from youthcentres where cat1='"+category+"' OR cat2 ='"+category+"' OR cat3='"+category+"'",null);
cur.moveToFirst();
myData.close();
return cur;
};
You now need to retrieve the data from the cursor using the appropriate getter methods.
For example, say you retrieved the following from the database:
1. Name (text) 2. Age (integer)
So, when you want to retrieve them from the cursor, you will go as follows:
String name = cur.getString(0);
int age = cur.getInt(1);
Remember that the zero-index is relative to the search query and not the table.
You may have columns in the table as (name,address,class,age) in which case age is at index 3. That doesn't matter to the cursor here :)
Related
I am having a table named keywords in database.I want to retrieve data of alarm and location columns from this table and unable to retrieve them except for contact number.For now I am showing their values in a Toast but every time I run any query to show my alarm or location in Toast its empty.But my contact_number is always shown.Don't understand the cause of this problem .I have also checked my tables view and it is showing the values of alarm ,location in them.
Create Table keywords( contact_number text primary key , alarm text , location text )
and my insert function is
public boolean insertkeys (String alarm ,String location ,String contact){
SQLiteDatabase db = this.getWritableDatabase();
//ContentValues is a name value pair, used to insert or update values into database tables.
// ContentValues object will be passed to SQLiteDataBase objects insert() and update() functions.
// ContentValues contentValues = new ContentValues();
ContentValues contentValues = new ContentValues();
contentValues.put("alarm",alarm);
contentValues.put("location",location);
contentValues.put("contact_number",contact);
long ins = db.insert("keywords",null,contentValues);
long upd = db.update("keywords",contentValues,"contact_number = ?",new String[]{contact});
// db.close();
if(ins == -1 && upd == -1)
return false;
else
return true;
}
I am inserting plus updating my data every single time my save button is clicked.Can anyone here tell how can I write a query to retrieve data of these fields and set it to Toast or Edit text. I am new to Database and stuck here for about a week. Thanks in advance for help :)
You extract data via a SELECT query which is returned as a Cursor when using the Android SDK.
The Cursor is similar to a table in that it has a number of rows, each with a set number of columns as determined by what you select.
To get all rows the SELECT query would be along the lines of :-
`SELECT * FROM keywords`
To do this using the Android SDK you could use the SQLiteDatabase query convenience method e.g. for the above you could use :-
Cursor cursor = db.query("keywords",null,null,null,null,null,null);
check the links above for the values/parameters that can be passed and how they correlate with the SELECT statement.
You then traverse the returned cursor extracting the data, typically using the Cursor's move??? methods. Noting that most will return false if the move could not be made and also noting that the original position in the Cursor is before the first row
As such you could have a method that returns a Cursor as per :-
public Cursor getAllKeys(){
SQLiteDatabase db = this.getWritableDatabase();
return db.query("keywords",null,null,null,null,null,null);
}
You could then process all the rows using :-
Cursor csr = yourDBHelper.getAllKeys();
while (csr.moveToNext()) {
String current_contact_number = csr.getString(csr.getColumnIndex("contact_number");
String current_alarm = csr.getString(csr.getColumnIndex("alarm");
String current_location = csr.getString(csr.getColumnIndex("location"));
...... your code to Toast or use the retrieved values
}
csr.close(); //<<<<<<<<<< you should always close a Cursor when finished with it.
Additional
In regard to the comment :-
Cursor query which you have suggested I tried to make changes in it
like putting column and where clause but after that it returns me
nothing when I execute it.Could you tell me that query too.
The following could be a method to retrieve just the alarm according to a contact number.
public String getAlarmByContactNumber(String contactNumber){
String rv = "";
SQLiteDatabase db = this.getWritableDatabase();
Cursor csr = db.query(
"keywords", //<<<<<<<<<<<< the FROM clause (less the FROM keyword) typically the name of the table from which the data is to be extracted (but can include JOINS for example, for more complex queries)
new String[]{"alarm"}, //<<<<<<<<<< A String[] of the column names to be extracted (null equates to * which means all columns) (note can be more complex and include functions/sub queries)
"contact_number=?", //<<<<<<<<<< WHERE clause (less the WHERE keyword) note **?** are place holders for parameters passed as 4th argument
new String[]{contactNumber},
null, //<<<<<<<<<< GROUP BY clause (less the GROUP BY keywords)
null, //<<<<<<<<<< HAVING clause (less the HAVING keyword)
null //<<<<<<<<<< ORDER BY clause (less the ORDER BY keywords)
);
if (csr.moveToFirst()) {
rv = csr.getString(csr.getColumnIndex("alarm"));
}
csr.close();
return rv;
}
The above assumes that you would only have/want one alarm per contact number.
The above is in-principle code, it has not been run or tested and may therefore contain some minor errors.
This is my code :
Db.getInstance().beginTransaction();
int i = Db.getInstance().delete("friends", null, null);
Log.e(TAG, "dropDB: " + i);
Db.getInstance().setTransactionSuccessful();
Db.getInstance().endTransaction();
I have searched the SO community, but cannot find what is wrong in this code. When I delete , the value of i is number of rows deleted, but still the database keeps returning rows.
Db is my own helper class in which I initialise the SQLiteDatabase's object and get getWritableDatabase().
May be nothing, but try only calling getInstance() once and setting it to a variable.
I use this in a CustomDialog when the user clicks the btnYES to delete the table.
I know the table only ever has one record because it hold a password so try this
db = helper.getReadableDatabase();
String q = "SELECT * FROM masterPW";
Cursor cursor = db.rawQuery(q,null);
// Above query gets TABLE_PW data from Col_IDI
// TABLE_PW will only ever have one row of data
int rowID = 99;
if(cursor.moveToFirst()){
rowID = cursor.getInt(cursor.getColumnIndex(Col_IDI));
str = cursor.getString(cursor.getColumnIndex(Col_MPW));
}
cursor.close();
// Line of code below WORKS deletes entire TABLE <=====
// Not a recommended way to re-set the master password
// db.delete(TABLE_PW, null, null);
I'm trying to retrieve the sum of a column from SQLITE. I am able to successfully get it.
But when I try to retrieve just the sum of 10 rows, it returns the sum of the entire column again. The query seems to be correct though.
public String getUnitsForWeek(Context context) throws IOException {
DataBaseHelper dbHelper = new DataBaseHelper(context);
String query = "SELECT sum(UNITS) FROM SERVICE_TABLE order by id DESC limit 7";
return String.valueOf(dbHelper.getString(query));
}
The dbHelper.getString method is:
public int getString(String query) {
String mypath = DB_PATH + DB_NAME;
SQLiteDatabase database = SQLiteDatabase.openDatabase(mypath, null,
SQLiteDatabase.OPEN_READWRITE);
Cursor cursor = null;
int i;
cursor = database.rawQuery(query, null);
cursor.moveToFirst();
i= cursor.getInt(cursor.getColumnIndex(cursor.getColumnName(0)));
return i;
}
Thanks.
SUM is an aggregate function that combines data from many rows into one. Since there is only one result row, LIMIT and ORDER BY are meaningless.
To sum UNITS on the 7 rows with highest ID, you can use a subselect:
SELECT SUM(UNITS) FROM (SELECT UNITS FROM SERVICE_TABLE ORDER BY id DESC LIMIT 7);
Can't you do a subelect?
SELECT sum(UNITS) FROM (SELECT UNITS FROM SERVICE_TABLE order by id DESC limit 7) s
I have large number of strings, approximately 15,000 that I stored in a SQLite database using the following code:
void addKey(String key, String value, String table) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_KEY, key); // Contact Name
values.put(KEY_VALUE, value); // Contact Phone
// Inserting Row
db.insert(table, null, values);
db.close(); // Closing database connection
}
And then i search through that database using the following method in order to pick out any strings that match the key im looking for:
public String searchKeyString(String key, String table){
String rtn = "";
Log.d("searchKeyString",table);
// Select All Query
String selectQuery = "SELECT * FROM " + table;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Log.d("searchKeyString","searching");
if(cursor.getString(1).equals(key))
rtn = rtn + "," + cursor.getString(2);
} while (cursor.moveToNext());
}
cursor.close();
db.close();
Log.d("searchKeyString","finish search");
return rtn;
}
The goal is to do this in real time as the user is typing on the keep board so response time is key and the way it stands now it takes over a second to run through the search.
I considered reading all of the items into an array list initially and sorting through that which might be faster, but i thought an array list of that size might cause memory issues. What is the best way to search through these entries in my database?
A couple of things you can do...
Change the return to a StringBuilder until the end.
Only use a readable version of the database (that's probably not making much difference though)
Do not get a new instance of the database every time, keep it opened until you don't need it anymore
Query for only what you need with the "WHERE" argument in the SQL query.
See the code below with some changes:
// move this somewhere else in your Activity or such
SQLiteDatabase db = this.getReadableDatabase();
public String searchKeyString(String key, String table){
StringBuilder rtn = new StringBuilder();
Log.d("searchKeyString",table);
// Select All Query
String selectQuery = "SELECT * FROM " + table + " WHERE KEY_KEY=?";
Cursor cursor = db.rawQuery(selectQuery, new String[] {key});
// you can change it to
// db.rawQuery("SELECT * FROM "+table+" WHERE KEY_KEY LIKE ?", new String[] {key+"%"});
// if you want to get everything starting with that key value
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Log.d("searchKeyString","searching");
rtn.append(",").append(cursor.getString(2));
} while (cursor.moveToNext());
}
cursor.close();
Log.d("searchKeyString","finish search");
return rtn.toString();
}
Note even if you want this to happen in "real-time" for the user, you will still need to move this to a separate Thread or ASyncTask or you are going to run into problems....
You should consider using SELECT * FROM your-table LIMIT 50, for example. And you can put two buttons "Back", "Next" on your view. If every page has max 50 items, the user is at page 1, and he taps "Next", then you can use this query:
SELECT * FROM your-table LIMIT 50 OFFSET 50
If your table contains most of text-data, and you want to integrate search deeply into your app, consider using virtual table with FTS.
Let sqlite do the hard lifting.
First off, add an index to the field you're searching for, if you don't have one already. Secondly, don't do a SELECT all with manual table scan, but rather use a query in the form
SELECT column_value
FROM my_table
WHERE column_key LIKE "ABC%"
This returns the least amount of data, and the sql engine uses the index.
i dunno about better but maybe it'd be faster to make queries for the selected strings one by one.
public String searchKeyString(String key, String table){
String rtn = "";
Log.d("searchKeyString",table);
// Select All Query
String selectQuery = "SELECT * FROM " + table + "WHERE column_1 = " + key;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
rtn = rtn + "," + cursor.getString(2);
}
cursor.close();
db.close();
Log.d("searchKeyString","finish search");
return rtn;
}
EDIT:
Well i dunno how those custom keyboard apps do it, but those AutoCompleteTextViews are hooked up to adapters. you could just as easily make a cursorAdapter and hook your auto-complete view to it.
http://www.outofwhatbox.com/blog/2010/11/android-autocompletetextview-sqlite-and-dependent-fields/
http://www.opgenorth.net/blog/2011/09/06/using-autocompletetextview-and-simplecursoradapter-2/
I have 2 edit boxes in my UI. I want to retrieve data from a table and I want to insert those retrieved data into those edit text boxes how can I insert data into those edit text boxes from cursor?
check your no. of column and its name cursor.getColumnCount() and cursor.getColumnName(0). respectively.if your column count is 2 then cursor have two column
cursor.moveToFirst();
String columnName1 = cursor.getColumnName(0);
String columnName2 = cursor.getColumnName(1);
String str1 = cursor.getString(cursor.getColumnIndex(columnName1)));
String str2 = cursor.getString(cursor.getColumnIndex(columnName2)));
editext1.seText(str1);
editext2.seText(str2);
after completion of getting data from database close your cursor using cursor.close();
// Activity.onCreate function
EditText etfirstname= (EditText)findViewById(R.id.firstname);
EditText etlastname= (EditText)findViewById(R.id.lastname);
MyDatabase database = new MyDatabase(this);
Cursor c = database.queryRaw("SELECT firstname, lastname FROM users WHERE id=1"); // query data from database
if(c.moveToFirst()){
etfirstname.setText(c.getString(0)); // read firstname
etlastname.setText(c.getString(1)); // read lastname
}
c.close(); // dont forget to close cursor!