【问题标题】:SQLException: No value specified for parameter 1SQLException: 没有为参数 1 指定值
【发布时间】:2020-05-13 14:18:42
【问题描述】:

我在执行应用程序时遇到以下错误:

java.sql.SQLException: 没有为参数 1 指定值

什么意思?

我的UserGroup 列表在我的道中:

public List<UsuariousGrupos> select(Integer var) {
    List<UsuariousGrupos> ug= null;
    try {
        conn.Connection();
        stmt = conn.getPreparedStatement("select id_usuario, id_grupo from usuarios_grupos where id_grupo ='" + var + "'");
        ResultSet rs = stmt.executeQuery();
        ug = new ArrayList<UsuariousGrupos>();
        while (rs.next()) {
            ug.add(getUserGrupos(rs));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        conn.Disconnected();
    }
    return ug;
}

public UsuariousGrupos getUserGrupos(ResultSet rs) {
    try {
        UsuariousGrupos ug = new UsuariousGrupos(rs.getInt("id_usuario"), rs.getInt("id_grupo"));
        return ug;
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}

我的托管 bean 中的用户组列表:

public List<UsuariousGrupos> getListOfUserGroups() {
    List<UsuariousGrupos> usuariosGruposList = userGrpDAO.select(var2);
    listOfUserGroups = usuariosGruposList;
    return listOfUserGroups;
}

我的 JSF 页面:

 <p:dataTable var="usergroups" value="#{usuariousGruposBean.listOfUserGroups}">
     <p:column headerText="" style="height: 0" rendered="false">
         <h:outputText value="#{usergroups.id_grupo}"/>
     </p:column>

我的数据表能够显示数据库中的组列表。但是,当我在数据表中选择单个行时,应用程序需要一些时间才能与我的数据库建立连接以显示所选结果。

此外,应用程序能够比其他应用程序更快地显示某些选定的结果,这很奇怪。它与我一开始指出的异常有关吗?

错误:

Disconnected
Connected!!
java.sql.SQLException: No value specified for parameter 1
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1075)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:929)
    at com.mysql.jdbc.PreparedStatement.checkAllParametersSet(PreparedStatement.java:2560)
    at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2536)
    at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2462)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2216)
    at br.dao.UsuariousGruposDAO.select(UsuariousGruposDAO.java:126)
    at br.view.UsuariousGruposBean.getListOfUserGroups(UsuariousGruposBean.java:54)


SEVERE: Error Rendering View[/index.xhtml]
javax.el.ELException: /index.xhtml @61,99 value="#{usuariousGruposBean.listOfUserGroups}": Error reading 'listOfUserGroups' on type br.view.UsuariousGruposBean
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)

【问题讨论】:

  • 错误出现在哪一行?
  • 错误出现在这两行:ResultSet rs = stmt.executeQuery();和 List usuariosGruposList = userGrpDAO.select(var2);
  • 您确定您的选择不是“从 id_grupo = 的 usuarios_grupos 中选择 id_usuario, id_grupo?”。这将解释参数 1 的缺失值。
  • 嗯,我确实试过了,我得到了以下错误。
  • 新错误似乎是一个新问题。也许您应该为此打开一个单独的问题并在此处接受 sql 异常的解决方案。

标签: java jsf jdbc


【解决方案1】:

java.sql.Connection上没有Connection()getPreparedStatement()这样的方法。

conn.Connection();
stmt = conn.getPreparedStatement("select id_usuario, id_grupo from usuarios_grupos where id_grupo ='" + var + "'");

conn 显然是 JDBC 代码的本土包装器。您的特定问题可能是由 getPreparedStatement() 方法背后的代码引起的。在委托给 real connection.prepareStatement() 方法之前,它显然在 SQL 字符串中附加了一个 ?

您可能不想听到这个,但是您的 JDBC 方法完全被破坏了。这种设计表明 JDBC Connection 被保存为静态或实例变量,它是 threadunsafe

您需要完全重写它,以便归结为以下正确用法和变量范围:

public List<UsuariousGrupos> select(Integer idGrupo) throws SQLException {
    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet resultSet = null;
    List<UsuariousGrupos> usuariousGrupos = new ArrayList<UsariousGrupos>();

    try {
        connection = database.getConnection();
        statement = connection.prepareStatement("select id_usuario, id_grupo from usuarios_grupos where id_grupo = ?");
        statement.setInt(1, idGrupo);
        resultSet = statement.executeQuery();

        while (resultSet.next()) {
            usuariousGrupos.add(mapUsuariousGrupos(resultSet));
        }
    } finally {
        if (resultSet != null) try { resultSet.close(); } catch (SQLException ignore) {}
        if (statement != null) try { statement.close(); } catch (SQLException ignore) {}
        if (connection != null) try { connection.close(); } catch (SQLException ignore) {}

    }

    return usuariousGrupos;
}

另见:


与具体问题无关,您还有另一个问题。以下异常

javax.el.E​​LException: /index.xhtml @61,99 value="#{usuariousGruposBean.listOfUserGroups}": 读取 br.view.UsuariousGruposBean 类型的“listOfUserGroups”时出错

表示您在 getter 方法而不是 (post)constructor 或 (action)listener 方法中执行 JDBC 工作。这也是一个非常糟糕的主意,因为在渲染响应期间可以多次调用 getter。相应地修复它。

另见:

【讨论】:

  • 您好,感谢您的信息和帮助!我现在正在经历它。抱歉,我是 JDBC 和 Java Web 应用程序开发的新手
【解决方案2】:

通常你在使用准备好的语句时会遇到这种错误并且忘记设置索引为 1 的参数。

在这种情况下,您正在使用准备好的语句,但没有任何准备,您手动创建查询字符串。

此外,您可能会遇到其他问题,因为您在撇号之间连接了 Integer。数值没有它们。

所以,应该是这样的:

stmt = conn.getPreparedStatement("select id_usuario, id_grupo from usuarios_grupos where id_grupo = " + var + ";");

但实际上你应该使用 getStatement() 之类的东西或正确使用 getPreparedStatement()(在 var 的位置放置一个 ? 和 setInteger() 来放置它。

所以最终的解决方案是:

stmt = conn.getPreparedStatement("select id_usuario, id_grupo from usuarios_grupos where id_grupo = ?;");
stmt.setInt(1, var);

【讨论】:

  • 嘿,是的,我已经尝试了你的建议。但是,我现在得到一个空指针异常。
  • 创建一个没有占位符的预处理语句并没有什么坏处。
【解决方案3】:

如果你使用

stmt = conn.getPreparedStatement("select id_usuario, id_grupo 
  from usuarios_grupos 
  where id_grupo = ?);

你必须

stmt.setInt(1, var);

之前

ResultSet rs = stmt.executeQuery();

为第一个参数(即参数 1)赋值。如果不是,您的异常将会发生。

【讨论】:

  • 严重:错误渲染视图[/index.xhtml] javax.el.E​​LException:/index.xhtml @61,99 value="#{usuariousGruposBean.listOfUserGroups}":读取“listOfUserGroups”时出错在 javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194) 在 javax.faces.component 的 com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114) 键入 br.view.UsuariousGruposBean .ComponentStateHelper.eval(ComponentStateHelper.java:182)
  • 当我选择行时,var2 是我选择的 id。我正在尝试将它传递给我在 dao 中的 select (Int var) 方法。
【解决方案4】:

最近我也遇到了这个问题,我用jdbcTemplate batchUpdate方法批量插入记录

void batchInsert(final List<EntryDataDO> doList) {
    jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps, int i) throws SQLException {
            final EntryDataDO dataDO = doList.get(i);
            if (dataDO == null){
                return;
            }
            ps.setString(1, dataDO.getId());
            ps.setString(2, dataDO.getDataCode());
            ...
        }

        @Override
        public int getBatchSize() {
            return doList.size();
        }
    });
}

原因是如果doList的第一个元素为null,它将直接返回并导致Caused by: java.sql.SQLException: No value specified for parameter 1但如果不是第一个元素为null,则batchUpdate是可以的,但记录会重复,例如第二个元素为空,第二个将复制第一条记录

insert into t (id,...) values (1,...),(1,...),(3,...)

所以解决方案是: 1.首先从doList中排除空元素 2.然后调用batchInsert(doListWithoutNull)即:不能排除元素内org.springframework.jdbc.core.BatchPreparedStatementSetter#setValues

【讨论】:

    【解决方案5】:
    ResultSet rs = stmt.executeQuery();
    

    在执行操作之前不要使用此行。

    【讨论】:

    • 可以使用ResultSet rs=new stmt.getResultSet();方法只是不执行 query()
    猜你喜欢
    • 2019-05-02
    • 2020-03-16
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多