安卓SQLite查询语句

26

我从EditText中获取了一个String值,并将其设置在SELECT QUERY WHERE条件之后

如下:

TextView tv = (TextView) findViewById(R.id.textView3);
EditTextet2 et = (EditText) findViewById(R.id.editText1);

String name = et.getText().toString();

Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE name = '"+name+"'", null); 

c.moveToNext();

tv.setText(c.getString(c.getColumnIndex("email")));

但它不起作用。 有什么建议吗?


3
打印名称并确保您获取到有效的名称。使用c.moveToFirst()代替C....next()并尝试。 - kosa
6个回答

42
尝试修剪字符串,确保没有额外的空格:
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE TRIM(name) = '"+name.trim()+"'", null);

像@thinksteep提到的那样,还需要使用c.moveToFirst()


9
这个例子很糟糕,容易发生SQL注入攻击。为什么不正确使用第二个参数,而是插入null呢? - Daniele Testa

39

这是一个完整的用于选择语句的代码。

SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("SELECT column1,column2,column3 FROM table ", null);
if (c.moveToFirst()){
    do {
        // Passing values 
        String column1 = c.getString(0);
        String column2 = c.getString(1);
        String column3 = c.getString(2); 
        // Do something Here with values
    } while(c.moveToNext());
}
c.close();
db.close();

5
请注意,使用 c.getString(c.getColumnIndex("column1")) 要比 c.getString(0) 更好:如果更改查询,您不必更新索引。 - Quentin S.
我也会转义名称参数以避免 SQL 注入。 - saniales

15

尝试使用以下语句:

Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE name = ?", new String[] {name});

Android要求WHERE子句与“?”进行比较,然后在查询的第二个参数中指定相同数量的 “?”(原本是null)。

正如Nambari所提到的,您应该使用c.moveToFirst()而不是c.moveToNext()

此外,名称中可能有引号吗?那也可能会出问题。


1
以下是代码内容。
String areaTyp = "SELECT " +AREA_TYPE + "  FROM "
            + AREA_TYPE_TABLE + " where `" + TYPE + "`="
            + id;

其中id是用于显示结果的条件。


3
这里存在 SQL 注入问题。 - M at

1
 public User searchUser(String name) {
    User u = new User();
    SQLiteDatabase db = this.getWritableDatabase(); //get the database that was created in this instance
    Cursor c = db.rawQuery("select * from " + TABLE_NAME_User+" where username =?", new String[]{name});
    if (c.moveToLast()) {
        u.setUsername(c.getString(1));
        u.setEmail(c.getString(1));
        u.setImgUrl(c.getString(2));
        u.setScoreEng(c.getString(3));
        u.setScoreFr(c.getString(4));
        u.setScoreSpan(c.getString(5));
        u.setScoreGer(c.getString(6));
        u.setLevelFr(c.getString(7));
        u.setLevelEng(c.getString(8));
        u.setLevelSpan(c.getString(9));
        u.setLevelGer(c.getString(10));
        return u;

    }else {
        Log.e("error not found", "user can't be found or database empty");
        return u;
    }

}

这是选择一个用户的代码。 首先,你需要初始化一个空对象,然后调用可写的数据库。 如果有多个用户,你需要使用游标来选择一个。 在这里,你可以选择以下方式之一:1-
   if (c.moveToLast()) { } //it return the last element in that cursor 

或者使用:2-
 if(c.moveToFirst()) {  } //return the first object in the cursor 

不要忘记,如果数据库为空,你需要处理这种情况,在我的情况下,我只返回一个空对象。

祝好运!


1
详细答案:
String[] selectionArgs = new String[]{name};
    Cursor c = db.rawQuery(
       "SELECT * FROM " + tabl1 + 
       " WHERE " + name + " = ? ", selectionArgs
    );

selectionArgs: 这个参数需要你想要进行比较的'name'

这里需要注意:"一个 Cursor 对象,该对象位于你所引用的表的第一条记录之前"。

因此,要移动到第一条记录:

c.moveToFirst();

getColumnIndex(String ColumnName) : 该方法返回给定列名的从零开始的列索引。

tv.setText(c.getString(c.getColumnIndex("email")));

如果你想在“name”列下搜索给定名称的多个行,则可以使用以下循环:

if (cursor.moveToFirst()){
    do{
        ////go traversing through loops
           
    }while(cursor.moveToNext());
}
    

这应该解决问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接