0

I'm using Android RowQueries way to retrieve my folders from db.

this is the parameter i'm checking:

protected final static String FOLDER_COLUMN_ID = "_id";

Those queries are retrieving 1 row as expected:

    String query1 = "SELECT * FROM " + FOLDER_TABLE + " WHERE 1";
    Cursor c1 = db.rawQuery(query1, null);
    c1.moveToFirst();


    String query2 = "SELECT * FROM " + FOLDER_TABLE + " WHERE _id = 1";
    Cursor c2 = db.rawQuery(query2, null);
    c2.moveToFirst();

And here is all perfect. My problem is when the parameters are replaced by ? and string[].

PS: The retrieved row has the "_id" column with the value 1

Those queries are all not working (same debug istance, no data retrieved):

    String query = "SELECT * FROM " + FOLDER_TABLE + " WHERE ? = ?";
    Cursor c = db.rawQuery(query, new String[]{FOLDER_COLUMN_ID, String.valueOf(_id)});
    c.moveToFirst();


    String query1 = "SELECT * FROM " + FOLDER_TABLE + " WHERE _id = ?";
    Cursor c1 = db.rawQuery(query1, new String[]{String.valueOf(_id)});
    c1.moveToFirst();


    String query2 = "SELECT * FROM " + FOLDER_TABLE + " WHERE ? = 1";
    Cursor c2 = db.rawQuery(query2, new String[]{FOLDER_COLUMN_ID});
    c2.moveToFirst();

I can't figure out why I have this problem, what I'm missing? Thanks all

EDIT

This is how I create my entity:

protected final static String FOLDER_TABLE = "folder";
protected final static String FOLDER_COLUMN_ID = "_id";
protected final static String FOLDER_COLUMN_PASSWORD_PROTECTED = "_password_protected";
protected final static String FOLDER_COLUMN_PASSWORD = "_password";
protected final static String FOLDER_COLUMN_NAME = "_name";
protected final static String FOLDER_COLUMN_PARENT_FOLDER_ID = "_parent_folder_id";
protected final static String FOLDER_COLUMN_PARENT_FOLDER_NAME = "_parent_folder_name";
protected final static String FOLDER_COLUMN_FULL_PATH = "_full_path";


String queryFolder = "CREATE TABLE " + FOLDER_TABLE + "(" +
        FOLDER_COLUMN_ID + " INTEGER PRIMARY KEY, " +
        FOLDER_COLUMN_PASSWORD_PROTECTED + " INTEGER, " +
        FOLDER_COLUMN_PASSWORD + " TEXT, " +
        FOLDER_COLUMN_NAME + " TEXT, " +
        FOLDER_COLUMN_PARENT_FOLDER_ID + " INTEGER, " +
        FOLDER_COLUMN_PARENT_FOLDER_NAME + " TEXT, " +
        FOLDER_COLUMN_FULL_PATH + " TEXT " +
        ");";
        db.execSQL(queryFolder);
Pier Giorgio Misley
  • 5,305
  • 4
  • 27
  • 66

2 Answers2

1

Concerning the last query which is

String query2 = "SELECT * FROM " + FOLDER_TABLE + " WHERE ? = 1";
Cursor c2 = db.rawQuery(query2, new String[]{FOLDER_COLUMN_ID});
c2.moveToFirst();

This will be interpreted as .. WHERE '_id' = 1 that is it will compare text constant with int constant. rawQuery() can not substitute parameters for database objects names. If you need variable columns, it should be done the same way as you build query string with FOLDER_TABLE. Kind of

String query2 = "SELECT * FROM " + FOLDER_TABLE + " WHERE "+ FOLDER_COLUMN_ID + "= 1";

And the first query, ..WHERE 1 is effectively no WHERE at all, it returns all rows.

Serg
  • 22,285
  • 5
  • 21
  • 48
-1

It looks like you are pretty close with the 2nd of your not working queries.

String query1 = "SELECT * FROM " + FOLDER_TABLE + " WHERE _id = ?";
    Cursor c1 = db.rawQuery(query1, new String[]{String.valueOf(_id)});
    c1.moveToFirst(); 

Two things though. First, I don't understand why you are using String.valueOf.

Second, I would suggest declaring a test variable, something like row_i_want, and using that instead of _id.

It looks like you dont have _id declared as a variable so passing it as a parameter would result in a null pointer exception. So your query would look something like this:

String row_i_want = "1";
String query1 = "SELECT * FROM " + FOLDER_TABLE + " WHERE _id = ?";
            Cursor c1 = db.rawQuery(query1, new String[]{row_i_want});
            c1.moveToFirst();

UPDATE for different explanation:

The reason why your 2nd query works is because you have hardcoded in the value of 1.

String query2 = "SELECT * FROM " + FOLDER_TABLE + " WHERE _id = 1"; 

This kind of query is nice for tests and proving you have something in your db, but not when you want a user to be able to provide input and search your db. For that, you need to use a dynamic condition, you need to use ? and a String [].

Lets pretend your Android app asks the user to search by a row, and oyu have an EditText that a user can type into.

EditText et_input;

After initializing the EditText, you can pull out its contents with this:

String input = user_input.getText().toString();

Now that you have input from the user, you can use it to query your db like so:

String query1 = "SELECT * FROM " + FOLDER_TABLE + " WHERE _id = ?";
Cursor c1 = db.rawQuery(query1, new String[]{input});

Your problem in your 4th query that you mistakenly used _id as your dynamic condition with your String[].

Chris Newman
  • 3,152
  • 1
  • 16
  • 17
  • 2
    Obviously, `String.valueOf` is there because var `_id` is declared as `int` or `long` – Selvin Jun 08 '16 at 14:29
  • Technically, he doesn't have a variable called _id in his code. We only know that there is a column in his SQLite db called _id (and we know that the values in that column can be int or long) because that's what is required. – Chris Newman Jun 08 '16 at 14:36
  • @ChrisNewman I omitted to post also my class since I copyed my db rows and i'm always working on them, the names posted – Pier Giorgio Misley Jun 08 '16 at 14:47
  • @PierGiorgioMisley do you have a variable named _id? I see that you have a variable called FOLDER_COLUMN_ID = "_id". But that would still mean you get NullPointerException from using _id as if it was a variable. – Chris Newman Jun 08 '16 at 14:53
  • @ChrisNewman if you check the second working query, i'm using "WHERE _id = 1" and it works, so the problem is not in the column's name – Pier Giorgio Misley Jun 08 '16 at 14:56