I have a List of contacts with check box.When the user checks the check box i have updated my table field selectedValue with value=1 .Now what i want is i wamna get all the contacts in comma seperated way where selectedValue=1.So for that i have written a query.But my result is not desired.
For eg
I have 4 contacts A,B,C,D in a list.Now if user selects A and C from the list and when i fire that query to get the contacs comma seperated,this is what i get
A,A,C,C
I dont know why 2 values of A and C are comming
Code
public StringBuilder getCheckedContact() {
database = getWritableDatabase();
StringBuilder values = new StringBuilder();
String query = "Select * From " + contactTable + " where " + selectedContact + "=1";
Cursor c = database.rawQuery(query, null);
while (c.moveToNext()) {
for (int i = 0; i < c.getCount(); i++) {
values.append(c.getString(c.getColumnIndexOrThrow(contactName)));
if (i != c.getCount() - 1) {
values.append(",");
}
}
}
c.close();
database.close();
return values;
}
Your while loop loops over the results once, then the for loop loops over the results second time. If you select 4 contacts, you'd get 4*4=16 results.
Why did you add the inner for loop?
This could be rewritten as follows:
public StringBuilder getCheckedContact() {
database = getWritableDatabase();
StringBuilder values = new StringBuilder();
String query = "Select * From " + contactTable + " where " + selectedContact + "=1";
Cursor c = database.rawQuery(query, null);
boolean firstItem = true;
while (c.moveToNext()) {
if(firstItem)
firstItem = false;
else
values.append(",");
values.append(c.getString(c.getColumnIndexOrThrow(contactName)));
}
c.close();
database.close();
return values;
}
Related
I would to like to display data from a local database table according to a user condition.
Code to display:
public void viewContact(){
String name = getIntent().getStringExtra("name").toString();
tvName.setText(name);
String phone = db.getContacts(name).toString();
tvPhone.setText(phone);
String web = db.getContacts(name.toString();
tvWeb.setText(web);
}
DBHelper.class:
public Cursor getContacts(String therapist_name){
String selectQuery = " SELECT therapist_phone, therapist_web " +
" FROM " + THERAPIST_TABLE + " WHERE " + THERA_NAME + " = " + "'" + therapist_name + "'";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
return cursor;
}
Can anyone point out where I've gone wrong?
Explanation:
The activity receives contact name from previous activity (hence getIntent()). Then with that, it would like to view data from database relating to the contact and thus would like to view the phone_number and website columns.
So if therapist_name is equal that of selected contact from previous activity, it would only display the therapist_number and therapist_website of that contact in the next activity.
You should have an Object Contact with the properties you want, and everytime you run the query, go trough the steps Ana said of checking if the cursor is null and moving to first (i personally check the size of the cursor also, to Log an error if is empty).
And then return the created object, so when you call the method, you have everything there, something like this:
public List<Contact> getContacts(String therapist_name){
List<Contact> listOfContacts = new ArrayList<>();
String selectQuery = " SELECT therapist_phone, therapist_web " +
" FROM " + THERAPIST_TABLE + " WHERE " + THERA_NAME + " = " + "'" + therapist_name + "'";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
//Save data in variables here
String ph_no = cursor.getString(0); // therapist contact
String web = cursor.getString(1); //therapist web
listOfContacts.add(new Contact(ph_no, web));
} while (cursor.moveToNext());
}
}
return listOfContacts;
}
This returns a list of objects, just in case there is more than one match. You can tweak it to get one, or the first match, and return just the Contact object, so you would have your data,
You are just returning cursor object. Read the data and then return the retrieved data.
Example:
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
//Save data in variables here
ph_no = cursor.getString(0); // therapist contact
web = cursor.getString(1); //therapist web
} while (cursor.moveToNext());
}
}
//pass an array of ph_no and web from here now
how to change this logic to work with more than 170 rows.
// Getting All test
public List<Test> getAllTests(String str) {
List<Test> testList = new ArrayList<Test>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_TESTS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
//select rows by input string
if(cursor.getString(1).equals(str)){
Test test = new Test();
test.setId(Integer.parseInt(cursor.getString(0)));
test.setTest(cursor.getString(1));
test .setResult(Integer.parseInt(cursor.getString(2)));
// Adding test to list
testList.add(test);
}
} while (cursor.moveToNext());
}
//close database
db.close();
//return list data
return testList;
}
I want to select all rows by input string. It logic work perfectly with 150 rows but after 160 work slowly and crash on 170 rows
how to change this logic to work with more than 170 rows?
// Getting All test
public List<Test> getAllTests(String str) {
List<Test> testList = new ArrayList<Test>();
// Select All Query
//String selectQuery = "SELECT * FROM " + TABLE_TESTS;
String selectQuery = "SELECT id,result FROM " + TABLE_TESTS + " where name ='" + str + "'";
// Now you are saving memory of one column.
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
Test test = new Test();
// moved outside loop to prevent creating new object every time.
do {
//select rows by input string
//if(cursor.getString(1).equals(str)){
// No need for if Codition any more
test.setId(Integer.parseInt(cursor.getString(0)));
//test.setTest(cursor.getString(1));
test.setTest(str);
test .setResult(Integer.parseInt(cursor.getString(2)));
// Adding test to list
testList.add(test);
//}
} while (cursor.moveToNext());
}
//close database
db.close();
//return list data
return testList;
}
EDITED: MISPELLED METHOD
Use
String selectQuery = "SELECT * FROM " + TABLE_TESTS + " WHERE " + your_id + " > " + String.valueOf(last_id) + " LIMIT 150";
as your query structure, and then keep track of the last row id like this`
int last_id;
do {
//select rows by input string
if(cursor.getString(1).equals(str)){
Test test = new Test();
last_id = Integer.parseInt(cursor.getString(0));
test.setId(last_id);
...
}
} while (cursor.moveToNext());
every time the loop ends, just query again your db; the rows will be fetched from the next one you need, because last_id variable dinamically change according to your progress.
Could try using same code differently in following way
// using sql query Differently
(SQliteDatabase) db.query(
"TABLE_TESTS" / table name /,
new String[] { "id", "result" } / columns names /,
"name = ?" / where or selection /,
new String[] { str } / selectionArgs i.e. value to replace ? /,
null / groupBy /,
null / having /,
null / orderBy /
);
Another approach could be to use LIMIT and OFFSET to get data in parts to improve performance
// using LIMIT AND OFFSET
public List<Test> getAllTests(String str) {
List<Test> testList = new ArrayList<Test>();
// Select All Query
Integer count = 0;
String countQuery = "SELECT count(id) FROM " + TABLE_TESTS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
if (cursor.moveToFirst()) {
count= c.getCount();
}
db.close();
int MAX_LENGTH = 150;
if ( count > 0 ) {
int total_length = ( count / MAX_LENGTH ) + 1;
for ( int i=0; i<total_length; i++) {
String selectQuery = "SELECT id,result FROM " + TABLE_TESTS + " LIMIT " + MAX_LENGTH + " OFFSET " + (i*MAX_LENGTH) ;
db = this.getWritableDatabase();
cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
Test test = new Test();
// moved outside loop to prevent creating new object every time.
do {
//select rows by input string
if(cursor.getString(1).equals(str)){
test.setId(Integer.parseInt(cursor.getString(0)));
//test.setTest(cursor.getString(1));
test.setTest(str);
test .setResult(Integer.parseInt(cursor.getString(2)));
// Adding test to list
testList.add(test);
}
} while (cursor.moveToNext());
}
//close database
db.close();
}
}
//return list data
return testList;
}
I'd like to get a value from a table. If the column does not contain any value, then I am going to insert one.
If there is a value, I want to notify the user that a value was inserted already. When my table does not contain anything it shows an error as Java Null Pointer Exception. I want to get a null value from my table. Please help.
String qu="select * from userinfos";
c=db.rawQuery(qu,null);
int count = c.getCount();
String[] values = new String[count + 1];
int i = 0;
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
values[i] = c.getString(c.getColumnIndex("mail"));
Toast.makeText(FiveActivity.this, values[i],Toast.LENGTH_LONG).show();
i++;
}
i=0;
if(values[i].equals(null))
{
String Query = "insert into userinfos (mail,pass) values ('"+ mailuser+ "','" + password + "')";
db.execSQL(Query);
Toast.makeText(FiveActivity.this,"Values Inserted",Toast.LENGTH_LONG).show();
}
else
{
for(int j=0;j<3;j++)
Toast.makeText(FiveActivity.this,"Already one Email-Id:"+ values[i]+" "+"you given. if you want to insert new mail and password then go to Delete app",Toast.LENGTH_LONG).show();
}
You just need to check your count value like below:
c=db.rawQuery(qu,null);
int count = c.getCount();
if(count==0)
{
////// No data found
}
else
{
/////data available
}
getCount ()
Returns the numbers of rows in the cursor
http://developer.android.com/reference/android/database/Cursor.html#getCount
this is a simple fonction to manage Usertable or others:
/**
* Check if data exist in table
*
* #param table
* The table to check data
* #param whereArgs
* The conditions to check the data
* #return boolean Return True while data exist; False while data not exist
*/
public boolean isDataExist(String table, String column, String[] whereArgs) {
boolean result = false;
SQLiteDatabase db = this.getWritableDatabase();
String sql = "select * from " + table + " where " + column + " = ?";
Cursor cursor = db.rawQuery(sql, whereArgs);
if (cursor.getCount() > 0) {
result = true;
}
cursor.close();
db.close();
return result;
}
I'm Parsing a JSON WebService and creating a array with data to INSERT and DELETE entries in a database.
I found the solution bulkInsert to insert multiple rows using database transactions inside a content provider, however, I am trying to do the same procedure to delete multiple lines.
The INSERT solution:
#Override
public int bulkInsert(Uri uri, ContentValues[] allValues) {
SQLiteDatabase sqlDB = mCustomerDB.getWritableDatabase();
int numInserted = 0;
String table = MyDatabase.TABLE;
sqlDB.beginTransaction();
try {
for (ContentValues cv : allValues) {
//long newID = sqlDB.insertOrThrow(table, null, cv);
long newID = sqlDB.insertWithOnConflict(table, null, cv, SQLiteDatabase.CONFLICT_REPLACE);
if (newID <= 0) {
throw new SQLException("Error to add: " + uri);
}
}
sqlDB.setTransactionSuccessful();
getContext().getContentResolver().notifyChange(uri, null);
numInserted = allValues.length;
} finally {
sqlDB.endTransaction();
}
return numInserted;
}
Using this call:
mContext.getContentResolver().bulkInsert(ProviderMyDatabase.CONTENT_URI, valuesToInsertArray);
Is there any way to delete multiple rows (with this array ID's) of database using content provider.
UPDATE:
I found this solution, using the `IN clause:
List<String> list = new ArrayList<String>();
for (ContentValues cv : valuesToDelete) {
Object value = cv.get(DatabaseMyDatabase.KEY_ROW_ID);
list.add(value.toString());
}
String[] args = list.toArray(new String[list.size()]);
String selection = DatabaseMyDatabase.KEY_ROW_ID + " IN(" + new String(new char[args.length-1]).replace("\0", "?,") + "?)";
int total = mContext.getContentResolver().delete(ProviderMyDatabase.CONTENT_URI, selection, args);
LOGD(TAG, "Total = " + total);
The problem is that, if the JSON return more than 1000 rows to insert, occurs error, because the SQLITE_MAX_VARIABLE_NUMBER is set to 999. It can be changed but only at compile time.
ERROR: SQLiteException: too many SQL variables
Thanks in advance
I solved this issue with this code:
if (!valuesToDelete.isEmpty()) {
StringBuilder sb = new StringBuilder();
String value = null;
for (ContentValues cv : valuesToDelete) {
value = cv.getAsString(kei_id);
if (sb.length() > 0) {
sb.append(", ");
}
sb.append(value);
}
String args = sb.toString();
String selection = kei_id + " IN(" + args + ")";
int total = mContext.getContentResolver().delete(uri, selection, null);
LOGD(TAG, "Total = " + total);
} else {
LOGD(TAG, "No data to Delete");
}
Thanks
User ContentResolver object to delete multiple rows.
// get the ContentResolver from a context
// if not from any activity, then you can use application's context to get the ContentResolver
// 'where' is the condition e.g., "field1 = ?"
// whereArgs is the values in string e.g., new String[] { field1Value }
ContentResolver cr = getContentResolver();
cr.delete(ProviderMyDatabase.CONTENT_URI, where, whereArgs);
So any row with (field1 = field1Value) will be deleted.
If you want to delete all the rows then
cr.delete(ProviderMyDatabase.CONTENT_URI, "1 = 1", null);
sqlite query for store all the data in single array.means I have a table where 8 fields are there and I want to retrive all the data in a single array and return array.
Can I do this?
Code from the comment below:
public String[] login1(String email) throws SQLException {
/* Cursor mCursor = db.rawQuery("SELECT * FROM " + TABLE_NAME
+ " WHERE email=? AND password=?",
new String[]{username,res});
*/
try {
/*Cursor c = db.rawQuery("select * from member where email ="
+ "\""+ email.trim() + "\""+" and password="
+ "\""+ res.trim() + "\"", null);
*/
Cursor c = db.rawQuery("Select usermasterid,invalidlogincount,password,"
+ "nextpage,status,user,businessnextpage "
+ "from member where email " + "\""+ email.trim()
+ "\"", null);
There is not enough info in your question, but it should be roughly like this(assuming your data is int):
public int[] getDBRowAsArray() {
int[] myArray = new int[8];
Cursor cursor = yourSQLiteOpenHelper.rawQuery("Your SQL query here", null);
for(int i = 0; i < 8; i++) {
myArray[i] = cursor.getInt(i);
}
return myArray;
}
I assume there are 8 records and not fields in the db.
public String[] getData(){
Cursor c = db.query(args...);
if(c != null && c.moveToFirst()){
int count = c.getCount();
String[] vals = new String[count];
for(int i = 0; i < count; i++){
vals[i] = c.getString(c.getColumnIndex(Table.COLUMN));
c.moveToNext();
}
c.close();
return vals;
}
return null;
}