You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android SQLite查询报no such column错误致应用崩溃

问题根因

崩溃来自SQL语法错误:你手动拼接SQL语句时,字符串类型的用户名、密码值没有包裹单引号,SQLite会直接把传入的rushi、4567识别为列名进行解析,最终抛出「不存在名为rushi的列」异常。
你当前拼接生成的错误SQL语句:

SELECT * FROM register WHERE Username = rushi and password = 4567;

注意:手动拼接SQL不仅容易出现这类语法错误,还存在SQL注入风险,正式开发必须使用参数化查询替代字符串拼接。

修复步骤

1. 重构DBHandler中的查询方法

移除从MainActivity取静态值的逻辑,将用户名、密码作为方法参数传入,使用?作为SQL参数占位符,由SQLite框架自动处理参数转义、引号拼接,修改后代码:

public Cursor CheckUsername(String inputUsername, String inputPassword) {
    SQLiteDatabase db = this.getReadableDatabase();
    String query = "SELECT * FROM register WHERE Username = ? AND password = ?";
    // 按占位符顺序传入参数值
    return db.rawQuery(query, new String[]{inputUsername, inputPassword});
}

2. 调整登录校验逻辑

直接使用当前页面从输入框获取到的用户名、密码调用查询方法,不再依赖跨类静态取值(该写法容易取到空值、旧值导致逻辑异常),同时补充游标资源释放、登录失败提示逻辑:

private void checkLogin() {
    EditText emailInput = findViewById(R.id.emaillogin);
    EditText pwdInput = findViewById(R.id.passwordlogin);

    String password = pwdInput.getText().toString();
    String username = emailInput.getText().toString().trim();

    Cursor c = dbHandler.CheckUsername(username, password);
    if (c.moveToFirst()) {
        Toast.makeText(MainActivity.this, "Login Success", Toast.LENGTH_LONG).show();
        startActivity(new Intent(MainActivity.this, MainActivity2.class));
    } else {
        Toast.makeText(MainActivity.this, "用户名或密码错误", Toast.LENGTH_LONG).show();
    }
    // 用完必须关闭游标,避免内存泄漏
    c.close();
}
开发建议
  • 所有数据库操作涉及动态传入参数时,统一使用?占位符的参数化查询,禁止手动拼接SQL语句
  • 数据库查询返回的Cursor对象使用完成后必须调用close()释放资源
  • 禁止明文存储用户密码,建议使用加盐哈希算法处理后再存入数据库,降低数据泄露风险

内容的提问来源于stack exchange,提问作者Rishi Ff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:27:28