我在执行应用程序时遇到以下错误:
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)
答案 0 :(得分:13)
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()
方法背后的代码引起的。在委托进入真正的 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.ELException:/index.xhtml @ 61,99 value =“#{usuariousGruposBean.listOfUserGroups}”:在类型br.view.UsuariousGruposBean上读取'listOfUserGroups'时出错
表示您在 getter 方法中而不是(post)构造函数或(action)侦听器方法中执行JDBC操作。这也是一个非常糟糕的主意,因为在渲染响应期间可以多次调用getter。相应地修复它。
答案 1 :(得分:3)
通常在使用预准备语句时会出现此类错误,并且忘记使用索引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);
答案 2 :(得分:2)
如果您使用
stmt = conn.getPreparedStatement("select id_usuario, id_grupo
from usuarios_grupos
where id_grupo = ?);
你必须
stmt.setInt(1, var);
前
ResultSet rs = stmt.executeQuery();
为第一个参数赋值(即参数1)。如果不是,您的例外将会发生。
答案 3 :(得分:0)
最近我也遇到了这个问题,我使用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可以,但是记录将重复,例如第二个元素为null,第二个元素将复制第一个记录
insert into t (id,...) values (1,...),(1,...),(3,...)
因此解决方案是:
1.首先从doList中排除null元素
2.然后调用batchInsert(doListWithoutNull),即:不能排除元素内部org.springframework.jdbc.core.BatchPreparedStatementSetter#setValues
答案 4 :(得分:0)
ResultSet rs = stmt.executeQuery();
在执行操作之前请勿使用此行。