I have the following function for SQLite select statement
public Boolean itemFound(String cartId,Long ItemId){
SQLiteDatabase db = this.getReadableDatabase();
Log.d("search",cartId+"--"+ItemId);
try {
String where = COL_ITEM_CART_ID+"='"+cartId+"' and "+COL_ITEM_ID+" ="+ ItemId+"";
Log.d("where===============", where);
String columns[] = new String[] { COL_ITEM_ID,COL_ITEM_NAME, COL_ITEM_PRICE, COL_ITEM_ADDDATE,COL_ITEM_QUANTITY,COL_ITEM_CART_ID }; // > null means * (all)
Cursor c = db.query(TABLE_NAME,
columns ,
COL_ITEM_CART_ID+"='?' and "+ COL_ITEM_ID + "=?" ,
new String[]{cartId,String.valueOf(ItemId)},
null,
null,
COL_ITEM_ADDDATE+" desc");
int numRows = c.getCount();
c.close();
db.close();
if(numRows>0)
return true;
else
return false;
} catch (SQLException e) {
db.close();
return false;
}
}
where the parameters are :
Long type itemId= 9882889921
String type cartId = ca1745ef-24eb-4da8-a1ea-9650d78ba5c0
Despite there is recode with these data. the returned rows is 0 , why ?
You have wrapped a ? in single quotes, change this:
COL_ITEM_CART_ID+"='?' and "+ COL_ITEM_ID + "=?"
The line above is trying to literally match COL_ITEM_CART_ID to a question mark, change it like this:
COL_ITEM_CART_ID + "=? and "+ COL_ITEM_ID + "=?"
The query method will sanitize your data input for you, so when you wrap the ?s with apostrophes, the apostrophes become part of the input string itself. This is causing your query to return 0 rows.
To fix the problem, remove change all instances of '?' to ?.
Related
I am using the following to fetch a string from my table. The cursor is always returning empty even when I have data in database. Is the query wrong?
public void find(String myNumber){
String[] thecolumns = new String[]{
ID,
FLAG};
cursor = sqlDb.query(MY_TABLE,
thecolumns, NUMBER + "='"
+ myNumber+ "'", null, null, null, null);
if (cursorToFetchAssets != null ) {
cursorToFetchAssets.moveToFirst();{
try{
//code to fetch
}catch{
//return when there are no rows found.
}
}
EDIT: NUMBER is of type string "...+ NUMBER + " TEXT,.. " and myNumber is also a string
FIXED: Issue was on the server side of my code. Not over here..
try this:
cursor = sqlDb.query(
MY_TABLE,
thecolumns,
NUMBER + "=?",
new String[]{String.valueOf(number)},
null, null, null);
I'm trying to execute a query on a SQLiteDatabase in Android, using the query() function. I want to pass the argument in SelectionArgs[], but when I'm using a IN statement, it doesn't seem to substitute the '?' with the correct argument.
My query looks like this:
temp = database.query(TABLE_NAME_ENTRIES,
new String[] {"_id", "Entry", "Summary"},
"_id IN ( ? )",
new String[] {ids}, null, null, null);
and it results in an empty Cursor. Debug gives me the information that the executed query uses a statement "_id IN ( ? )", showing that it doesn't seem to replace the '?' as expected. When I change the query to
temp = database.query(TABLE_NAME_ENTRIES,
new String[] {"_id", "Entry", "Summary"},
"_id IN ( " + ids + " )",
null, null, null, null);
instead, I get the expected result.
I'm really stupid on this problem, any ideas what I'm doing wrong?
You could use a workaround like this - creating a method that generates dynamically your string with ? and , and put it in the query like this:
String[] ids = { "id1", "id2" }; // do whatever is needed first
String query = "SELECT * FROM table"
+ " WHERE _id IN (" + makePlaceholders(ids.length) + ")";
Cursor cursor = mDb.rawQuery(query, ids);
String makePlaceholders(int len) {
if (len < 1) {
// It will lead to an invalid query anyway ..
throw new RuntimeException("No placeholders");
} else {
StringBuilder sb = new StringBuilder(len * 2 - 1);
sb.append("?");
for (int i = 1; i < len; i++) {
sb.append(",?");
}
return sb.toString();
}
}
P.S. I think that the spaces before and after the question mark in your query could be wrong there, but I didn't test it, so I can't be 100% sure
i'm wondering if this method is right to verify if the value of _username already exists in the column "username"
public boolean verification(String _username) throws SQLException{
Cursor c = dataBase.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+KEY_USERNAME+"="+_username, null);
if (c!=null)
return true; // return true if the value of _username already exists
return false; // Return false if _username doesn't match with any value of the columns "Username"
}
Is there a better way to do the same thing, i'm really not sure about this, it seemed right for me.
Thanks.
Beware of SQL injection attacks! You should always use a parameterized query:
Cursor c = dataBase.rawQuery("SELECT 1 FROM "+TABLE_NAME+" WHERE "+KEY_USERNAME+"=?", new String[] {_username});
(Honestly I'm not sure how your first query didn't throw an exception since you forgot to wrap the string in quotes...)
Also rawQuery() will always return a Cursor, you must check if the Cursor is empty, not null.
As for "the best" approach, this works fine, but I recommend closing the Cursor to free up resources. All together:
public boolean verification(String _username) {
Cursor c = dataBase.rawQuery("SELECT 1 FROM "+TABLE_NAME+" WHERE "+KEY_USERNAME+"=?", new String[] {_username});
boolean exists = c.moveToFirst();
c.close();
return exists;
}
Is there a better way to do the same thing, i'm really not sure about
this, it seemed right for me. Thanks.
In the terms of security and purity yes, for sure.
public boolean verification(String _username) throws SQLException {
int count = -1;
Cursor c = null;
try {
String query = "SELECT COUNT(*) FROM "
+ TABLE_NAME + " WHERE " + KEY_USERNAME + " = ?"
c = dataBase.rawQuery(query, new String[] {_username});
if (c.moveToFirst()) {
count = c.getInt(0);
}
return count > 0;
}
finally {
if (c != null) {
c.close();
}
}
}
I recommend you to an usage of ? that is called placeholder. Each placeholder will be replaced with value from string array in the same order. This is called also parametrized statement as a defence agains SQL injection. When your work with Cursor is finished, release it.
I have written method which should return string with data from select query, but it doesn't work perfectly as I would like, here is method:
public String selectorDanych(String kolumna, String log){
String test = "Select "+ kolumna + " from "+ Usr_TABLE+ " where "+colLogin + " ='" +log+"';";
Cursor cursor2 = sqLiteDatabase.rawQuery(test, null);
return cursor2.toString();
}
it returns some kind of string but, it is not the thing I want [ the string it returns is something like "SQLite.database.#" etc
You're returning the internal name of the Cursor you got from the query, not any data from the query results.
You should use something like:
cursor2.moveToFirst(); // position the cursor at the first returned row
String col = cursor2.getString(the_index_of_the_column_you_want);
cursor2.close();
return col;
Make sure you test for errors though (there might be no rows returned at all), and read the Cursor API docs.
Rewrite your code as
public String selectorDanych(String kolumna, String log){
String test = "Select "+ kolumna + " from "+ Usr_TABLE+ " where "+colLogin + " ='" +log+"';";
Cursor cursor2 = sqLiteDatabase.rawQuery(test, null);
//Write these codes
if(cursor2.moveToFirst()) {
cursor2.close(); //You should close your cursor
return cursor2.getString(0); //index of your kolumna field
} else {
cursor2.close(); //You should close your cursor
return null; //Return some error msg, to notify that data not found
}
}
You can use the code below. You may catch exception after the try block. Even if you don't, you're guaranteed that the close() on the cursor will be called! I also suggest to always use English names for your vars.
public String selectorDanych(String kolumna, String log){
String test = "Select "+ kolumna + " from "+ Usr_TABLE+ " where "+colLogin + " ='" +log+"';";
Cursor cursor2 = sqLiteDatabase.rawQuery(test, null);
if (cursor2 != null && cursor2.moveToFirst()) {
try { //use try - finally to close the cursor in the finally block
int index_kolumna = cursor2.getColumnIndexOrThrow(kolumna);
String kolumna_val = cursor2.getString(index_kolumna);
} finally {
if (cursor2 != null && !cursor2.isClosed()) {
cursor2.close();
}
}
}
i am trying to do a query of my database for a string lets call it "Test" and then find out what row that particular string is in and save that number to use. I thought i had this figured out before but now it is not working for some reason and i get an error saying no such column "Test".
here is my code
public String getRow(String value){
ContactDB db = new ContactDB(this);
db.open();
Cursor curs = db.getId(value);
String test = curs.getString(curs.getColumnIndex(db.NAME));
curs.close();
Log.v("Contact", "Row ID: " + test);
db.close();
return test;
}
"Test" is sent into that as value
this is in my database
//---retrieve contact id---
public Cursor getId(String where){
Cursor c = db.query(DATABASE_TABLE, new String[] {ID},where,null,null,null,null);
if (c != null)
c.moveToFirst();
return c;
}
i dont remember changing anything from when i first tested it so i dont know why it wont work now
There are 2 errors that i could notice:
In the query
Cursor c = db.query(DATABASE_TABLE, new String[] {ID},where,null,null,null,null);
only the ID column is selected whereas you are trying to fetch details for column NAME
String test = curs.getString(curs.getColumnIndex(db.NAME));
include the name column as well in the select clause : something like
Cursor c = db.query(DATABASE_TABLE, new String[] {ID,NAME},where,null,null,null,null);
In the where clause you need to write the condition string excluding "where"
in your case String where contains value "Test". Hence the filter condition should be as
String whereClasue = NAME + " = '" + where + "'";
The query should be something like this:
public Cursor getId(String where){
Cursor c = db.query(DATABASE_TABLE, new String[] {ID,PHONE_NUMBER,NAME},NAME + " = '" + where + "'",null,null,null,null);
if (c != null)
c.moveToFirst();
return c;
}