【问题标题】:java.sql.SLQException: Illegal operation on empty result set [closed]java.sql.SLQException:对空结果集的非法操作[关闭]
【发布时间】:2017-05-08 02:40:27
【问题描述】:

我在 java 中有一个登录系统,我想从数据库中获取用户、密码和用户类型。但是当我运行程序时出现以下错误:java.sql.SLQException: Illegal operation on empty result set 代码:

    conn=MysqlConnect.ConnectDB();
    String Sql="Select*from utilizador where Nome='" + Username +"' and Password='" + Password +"' and Permissao'" + Permissao + "'" ;

    try{
        pst=conn.prepareStatement(Sql);
        Statement st = conn.createStatement();
        ResultSet rs = st.executeQuery(Sql);
        int permissao = rs.getInt("Permissao");
        String nome = rs.getString("Nome");
        String password = rs.getString("Password");

        if(rs.next()){

【问题讨论】:

  • 1.使用准备好的语句。 2. 您的查询在permissao 部分缺少=。 3.阅读异常信息。它试图告诉你一些事情。
  • Permissao'XYZ'??你甚至读过你自己的查询吗?

标签: java sql jdbc


【解决方案1】:

您的代码存在各种问题:

  • 您在and Permissao 之后错过了=
  • 从您的代码看来,您正在寻找通过以下字段过滤的用户:用户名、密码和 Permissao,因此您应该定义 3 个变量
  • 您正在尝试在选择任何行之前访问 ResultSet(使用 rs.getXXX)。在executeQuery 方法之后,您“填充”了一个ResultSet,但他的索引未指向任何有效的“数据库行”,因此您需要调用“rs.next()”才能将索引移动到第一行。连续调用每次将索引移动到 1 个位置,直到 ResultSet 完成。

话虽如此,你应该:

  1. 使用准备好的语句来防止 sql 注入和其他拼写错误/字符错误,因为它会自动转义参数值。

  2. 在准备好的语句中使用? 来定义您需要使用s.set<TypeOfField> 设置的参数

  3. 在使用rs.get之前检查ResultSet是否有行

  4. 在 finally 子句中关闭连接、语句和结果集,因此无论是否存在异常都会关闭资源。这样做可以防止由于您不再使用的已打开资源而导致内存泄漏。

  5. 你应该有 3 个变量来执行选择:(我想)

    • 字符串类型的用户名
    • 字符串类型的密码
    • int/Integer 类型的 Permissao

尝试使用适合您需要的以下代码。

    Connection c = DB.dbConnect(null);
    PreparedStatement s = null;
    ResultSet rs = null;
    try {
        final String SQL = " Select * from utilizador where Nome=? and Password=? and Permissao = ? ";

        s = c.prepareStatement(SQL);

        int i = 1;
        s.setString(i++, Username);
        s.setString(i++, Password);
        s.setInt(i++, Permissao);

        rs = s.executeQuery();
        if (rs.next()) {
             int permissao = rs.getInt("Permissao");
             String nome = rs.getString("Nome");
             String password = rs.getString("Password");
        }

    } catch (SQLException e) {          
        // exception handler
    } finally {
        try {
            if (rs != null)
                rs.close();
        } catch (Exception e) {
        }
        try {
            if (s != null)
                s.close();
        } catch (Exception e) {
        }try {
            if (c != null)
                c.close();
         } catch (Exception e) {
        }
    }

【讨论】:

  • 我建议您先回答这个问题(这就是发生此错误的原因(即:在使用getXXX 之前没有调用rs.next()),然后继续解决另一个问题问题中的代码存在问题。这让您更明显地知道您实际上是在回答问题。
  • 它在“ s.setString(i++, Username);/ s.setString(i++, Password); 处给了我以下错误;
  • 它在“ s.setString(i++, Username);/s.setString(i++, Password); 处出现以下错误;不兼容的类型:JPasswordField 无法转换为字符串
  • 您应该分别拥有Username, Passord and PermissaoString,String, Integer。因此,您需要在使用 s.setXXX 设置语句之前转换/提取值
  • 关于 JPasswordField 的问题请查看:stackoverflow.com/questions/983964/…
【解决方案2】:

难看、不可读的代码。

这是你的问题:

    String nome = rs.getString("Nome");
    String password = rs.getString("Password");

在检查它是否有任何行之前,您尝试访问 ResultSet 中的值。

【讨论】:

  • 我是新人,这是我自己做的第一个程序
  • 我会说第一个程序涉及关系数据库是不寻常的。帮自己一个忙:学习 Java 编码标准,虔诚地遵循它们,并开始关注格式和样式。您的代码很难阅读。这会让你和其他人更难阅读和理解你的代码。
【解决方案3】:

显然,问题在于您的查询缺少正确的引号和空格。应该是

   String Sql="Select * from utilizador where Nome = '" + Username +"' and Password='" + Password +"' and Permissao = '" + Permissao + "'" ;

【讨论】:

  • 我不认为修复引号是正确的做法 - 他们应该正确使用准备好的语句,而不是首先将未经处理的值直接转储到 SQL 中。
  • SELECT*FROM 之类的东西看起来不对,但它在 MySql 中有效。真正的问题是在最后一个条件下缺少=
  • @JonK,当然,但首先是我的建议。
  • @f1sh,不错不错。谢谢指点。
  • 我把“=”,它一直给我同样的错误
猜你喜欢
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-23
  • 2017-09-17
  • 2013-03-28
相关资源
最近更新 更多