sqlite rand() unique _id return sqlite - android

How can i get a predifined(users choise) number of rows from my database and ensure that i display them only once? If use rand() limit 1, and return the cursor the same _id may return twice or more.
I use this
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query("THESIS Order BY RANDOM() LIMIT 1",new String[] { "*" }, null, null, null, null, null);
cursor.moveToFirst();
return cursor;

SELECT DISTINCT column_name(s) FROM table_name
distinct world will return unique output it will not give you repeated data

Related

retrieve particular column between different columns of sqlite databse in android

Here is the code, by this I can retrieve all the columns data from the database. But the problem is that now I want to retrieve only one column, that is my requirement.link1st link 2nd link3rd
word_list = new ArrayList<>();
SQLiteDatabase sd = mydb.getWritableDatabase();
Cursor cursor = sd.query("stickerstable",null, null, null, null, null, null);
if (cursor.moveToFirst()){
do{
word_list.add(new data_items(
cursor.getInt(cursor.getColumnIndex(ID)),
cursor.getString(cursor.getColumnIndex(STICKER_AUTHOR)),
cursor.getString(cursor.getColumnIndex(STICKER_NAME)
)));
}while (cursor.moveToNext());
cursor.close();
sd.close();
}
You can use rawQuery instead of query
Cursor cursor = sd.rawQuery("SELECT YOUR_COLUMN FROM stickerstable",null);
replace YOUR_COLUMN with the name of column you want to retrieve you can even use your Constants like this
Cursor cursor = sd.rawQuery("SELECT " + ID + " FROM stickerstable",null);
or a better way to use String.format
Cursor cursor = sd.rawQuery(String.format("SELECT %s FROM stickerstable", ID),null);
UPDATE
you can use query and specify the column in the second argument
Cursor cursor = sd.query("stickerstable",new String[]{ID}, null, null, null, null, null);
when you pass null means get all columns

Returning sqlite query as cursor or object/list

When I started my app years ago, I did some tutorials and always did my queries to the database returning the cursor (without closing it):
public Cursor querySingleId(String szId) {
SQLiteDatabase db = getWritableDatabase();
return db.query(TABLE_ADR, szGetTableEntries, _ID + " = ?", new String[]{szId}, null, null, null);
}
Now I am refactoring my code to MVVM and added models, so I changed my code to this:
public Card querySingleId(String szId) {
SQLiteDatabase db = getWritableDatabase();
Cursor c1 = db.query(TABLE_ADR, szGetTableEntries, _ID + " = ?", new String[]{szId}, null, null, null);
c1.moveToFirst();
return new Card(c1.getString(c1.getColumnIndex(DbHandler.NAME)),
c1.getString(c1.getColumnIndex(DbHandler.STREET)),
c1.getString(c1.getColumnIndex(DbHandler.CITY)));
}
I read that cursors should always be closed (memory leak). Which is the best/most conform approach to return my data from the database? I'm also unsure if there are multiple results, should I stay with a cursor or change to a list?
public List<Card> queryAll() {
SQLiteDatabase db = getWritableDatabase();
Cursor c1 = db.query(TABLE_ADR, szGetTableEntries, null, null, null, null, null);
List<Card> list = new ArrayList<>();
if(c1.moveToFirst()){
do{
list.add(new Card(c1.getString(c1.getColumnIndex(DbHandler.NAME)),
c1.getString(c1.getColumnIndex(DbHandler.STREET)),
c1.getString(c1.getColumnIndex(DbHandler.CITY))));
} while(c1.moveToNext());
}
c1.close();
return list;
}
Is this all just a matter of taste or are there reasons why it should return a cursor or a list/object? Depending where in my code I need the data, a list or a cursor is more convenient.
I'm just not sure what is the correct approach in sqlite queries. There are so many code examples and but it seems most is copy/paste without really digging into the topic.
If the query can return multiple rows then you should return a list.
If you are sure that the query will return just a single Card then returning that single Card would be OK (probably preferable) BUT you should close the Cursor.
However, there isn't an actual requirement/need to do so (e.g. if you your initial activity uses a Cursor for a ListView/Spinner then you may not want to close the Cursor but reuse it and use the adapter's swapCursor when the Activity resumes). The cursor would be effectively closed, as would the database when the App finishes.
As you have used the column _ID which is typically used for a column that is an alias of the rowid column, which is typically generated by SQLite then if used/defined as such (column has been defined explicitly or implicitly as INTEGER PRIMARY KEY with or without AUTOINCREMENT) then it will be a unique value and only return a single row as you have _ID = ?. As such there is a high likeliehood that a single row, or no row would be returned, and unlikely that multiple rows are returned.
So (for a single Card):-
public Card querySingleId(String szId) {
SQLiteDatabase db = getWritableDatabase();
Cursor c1 = db.query(TABLE_ADR, szGetTableEntries, _ID + " = ?", new String[]{szId}, null, null, null);
c1.moveToFirst();
return new Card(c1.getString(c1.getColumnIndex(DbHandler.NAME)),
c1.getString(c1.getColumnIndex(DbHandler.STREET)),
c1.getString(c1.getColumnIndex(DbHandler.CITY)));
}
Should be something like :-
public Card querySingleId(String szId) {
SQLiteDatabase db = getWritableDatabase();
Card rv = null;
Cursor c1 = db.query(TABLE_ADR, szGetTableEntries, _ID + " = ?", new String[]{szId}, null, null, null);
if (c1.moveToFirst()) { //<<<<<< Should always check if the move moved
rv = new Card(c1.getString(c1.getColumnIndex(DbHandler.NAME)),
c1.getString(c1.getColumnIndex(DbHandler.STREET)),
c1.getString(c1.getColumnIndex(DbHandler.CITY)));
}
c1.close();
return rv; //<<<<< Note should check the returned Card for null
}
In addition to memory leaks not closing Cursors can result in a too many open connections (1K (1024) if memory serves correctly) and then a exception: unable to open database file (code 14); as underneath all the wrappers a Cursor has a file associated with it.

How to search multiple columns in SQLite db?

I got a problem when trying to search in multiple columns of a SQLite db.
Here ist my current code
String whereClause;
if (!suchwort.contains("%")){ // Abfrage mit Wildcard?
whereClause = WoerterbuchContract.WoerterbuchEintraege.COLUMN_NAME_WORT_DEUTSCH
+ " = '"+suchwort+"'" ;}
else {
whereClause = WoerterbuchContract.WoerterbuchEintraege.COLUMN_NAME_WORT_DEUTSCH
+" like '"+suchwort+"'";}
Cursor ergCursor = db.query(
WoerterbuchContract.WoerterbuchEintraege.TABLE_NAME, // The table to query
projection, // The columns to return
whereClause, // WHERE clause
null, // no values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
I tried adding columns to my whereClause, but i allways get compiler errors.

how to filter multiple data on multiple column sqlite database

i want to filter multiple data such as
id = "1,3,5" from columnid which is having 1 to 10 id
and another column such as name
name = "a,e,d" from name column of 10 records
and another criteria such as age
age = "21,23,20" from age column of 10 records from same table,
one example i got is
Cursor cursor = db.query("TABLE_NAME",new String[]{"ColumnName"}, "ColumnName=?",new String[]{"value"}, null, null, null);
which is just for one column but i want to get data from multiple column, can anyone help me?
try this working example,
Cursor cursor =
db.query(TABLE_DIARYENTRIES,
new String[] {},
STUDENT_ID + " IN ("+resultStudent+")"+ " AND " +CLASS_NAME + " IN ("+resultClass+")"
+ " AND " +SUBJECT_NAME + " IN ("+resultSubject+")"
null, null, null, null);
and your result string should be 'a','b','c'
I really like the way Google's example is structured. Because for noobies such as myself it makes it really clear what I am doing. And it is also more robust to SQL injections. Here is my modified version of the Google example:
//Column(s) I want returned
String[] projection = {"ColumnIWantReturned"};
//Column(s) I want to filer on
String selection = "FilterColumn1 IN (?) and FilterColumn2 IN (?, ?)";
String[] selectionArgs = {"ArgumentForFilterColumn1", "FirstArgumentForFilterColumn2", "SecondArgumentForFilterColumn2"};
Cursor cursor = db.query(
"MyTable", // The table to query
projection, // The array of columns to return (pass null to get all)
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Log.d("this-is-a-test", cursor.getString(0));
cursor.moveToNext();
}
cursor.close();

Changing order of listview results from SQlite

I have a listview in my application that displays records according to the primary key _ID field with the lowest _ID number first. How can I change that so it is the highest _ID number first in the listview? i.e reverse the order.
The db query currently generating the listview is below. Thanks!
public Cursor fetch() {
String[] columns = new String[] { DatabaseHelper._ID, DatabaseHelper.SLOC, DatabaseHelper.FLOC, DatabaseHelper.DSNM, DatabaseHelper.SDATE, DatabaseHelper.STIME };
Cursor cursor = database.query(DatabaseHelper.TABLE_NAME, columns, null, null, null, null, null);
if (cursor != null) {
cursor.moveToLast();
}
return cursor;
}
use this query:
Cursor c = mDb.query(DATABASE_TABLE, rank, null, null, null, null, yourColumn+" DESC");
You can use rawQuery method to hit any custom query like this and add ORDER BY ASC or DESC as you wish.
public Cursor fetch() {
String queryString = "SELECT * FROM tablename ORDER BY _id DESC"
Cursor cursor = sqLiteDatabase.rawQuery(queryString);
if (cursor != null) {
cursor.moveToLast();
}
return cursor;
}

Categories

Resources