当我执行以下代码时,一切都很好:
ResultSet rs = con.prepareStatement("SELECT r.UID AS R FROM r").executeQuery();
System.out.println(rs.getMetaData().getColumnLabel(1));
rs.next();
System.out.println(rs.getString("R"));
结果是:
R
23
但是当我执行以下代码时:
ResultSet rs = con.prepareStatement("SELECT r.UID AS R FROM r").executeQuery();
CachedRowSetImpl rslt = new CachedRowSetImpl();
rslt.populate(rs);
System.out.println(rslt.getMetaData().getColumnLabel(1));
rslt.next();
System.out.println(rslt.getString("R"));
结果是:
R
java.sql.SQLException: Invalid column name
为什么在这里抛出异常?
问题是,参考实现CachedRowSet
(com.sun.rowset.CachedRowSetImpl
)包含一个错误:当您通过名称检索列,它使用的columnName
,而
不是
在columnLabel
,为此逆着它使用JDBC规范的其余部分columnLabel
检索值。此错误使得不可能通过来从行集中检索值columnLabel
。
Oracle的错误是http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7046875,但是(感到惊讶)他们使该错误无法供公众查看。
有两种可能的解决方法。一种是检查驱动程序是否提供了一个属性,以使该ResultSetMetaData.getColumnName(..)
方法也返回该columnLabel
值,第二种解决方法是创建的子类CachedRowSetImpl
(不幸的是,它需要很多重写方法)。
以下版本是从此消息复制的:http : //tech.groups.yahoo.com/group/Firebird-
Java/message/10715
import java.math.BigDecimal;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Ref;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Collection;
import java.util.Hashtable;
import javax.sql.rowset.RowSetMetaDataImpl;
import com.sun.rowset.CachedRowSetImpl;
public class FixedCachedRowSetImpl extends CachedRowSetImpl {
private static final long serialVersionUID = -9067504047398250113L;
private RowSetMetaDataImpl RowSetMD;
public FixedCachedRowSetImpl() throws SQLException {
super();
}
public FixedCachedRowSetImpl(Hashtable env) throws SQLException {
super(env);
}
private int getColIdxByName(String name) throws SQLException {
RowSetMD = (RowSetMetaDataImpl) this.getMetaData();
int cols = RowSetMD.getColumnCount();
for (int i = 1; i <= cols; ++i) {
String colName = RowSetMD.getColumnLabel(i);
if (colName != null) if (name.equalsIgnoreCase(colName))
return (i);
else
continue;
}
throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalcolnm").toString());
}
@Override
public Collection<?> toCollection(String column) throws SQLException {
return toCollection(getColIdxByName(column));
}
@Override
public String getString(String columnName) throws SQLException {
return getString(getColIdxByName(columnName));
}
@Override
public boolean getBoolean(String columnName) throws SQLException {
return getBoolean(getColIdxByName(columnName));
}
@Override
public byte getByte(String columnName) throws SQLException {
return getByte(getColIdxByName(columnName));
}
@Override
public short getShort(String columnName) throws SQLException {
return getShort(getColIdxByName(columnName));
}
@Override
public int getInt(String columnName) throws SQLException {
return getInt(getColIdxByName(columnName));
}
@Override
public long getLong(String columnName) throws SQLException {
return getLong(getColIdxByName(columnName));
}
@Override
public float getFloat(String columnName) throws SQLException {
return getFloat(getColIdxByName(columnName));
}
@Override
public double getDouble(String columnName) throws SQLException {
return getDouble(getColIdxByName(columnName));
}
@Override
public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {
return getBigDecimal(getColIdxByName(columnName), scale);
}
@Override
public byte[] getBytes(String columnName) throws SQLException {
return getBytes(getColIdxByName(columnName));
}
@Override
public java.sql.Date getDate(String columnName) throws SQLException {
return getDate(getColIdxByName(columnName));
}
@Override
public java.sql.Time getTime(String columnName) throws SQLException {
return getTime(getColIdxByName(columnName));
}
@Override
public java.sql.Timestamp getTimestamp(String columnName) throws SQLException {
return getTimestamp(getColIdxByName(columnName));
}
@Override
public java.io.InputStream getAsciiStream(String columnName) throws SQLException {
return getAsciiStream(getColIdxByName(columnName));
}
@Override
public java.io.InputStream getUnicodeStream(String columnName) throws SQLException {
return getUnicodeStream(getColIdxByName(columnName));
}
@Override
public java.io.InputStream getBinaryStream(String columnName) throws SQLException {
return getBinaryStream(getColIdxByName(columnName));
}
@Override
public Object getObject(String columnName) throws SQLException {
return getObject(getColIdxByName(columnName));
}
@Override
public int findColumn(String columnName) throws SQLException {
return getColIdxByName(columnName);
}
@Override
public java.io.Reader getCharacterStream(String columnName) throws SQLException {
return getCharacterStream(getColIdxByName(columnName));
}
@Override
public BigDecimal getBigDecimal(String columnName) throws SQLException {
return getBigDecimal(getColIdxByName(columnName));
}
@Override
public boolean columnUpdated(String columnName) throws SQLException {
return columnUpdated(getColIdxByName(columnName));
}
@Override
public void updateNull(String columnName) throws SQLException {
updateNull(getColIdxByName(columnName));
}
@Override
public void updateBoolean(String columnName, boolean x) throws SQLException {
updateBoolean(getColIdxByName(columnName), x);
}
@Override
public void updateByte(String columnName, byte x) throws SQLException {
updateByte(getColIdxByName(columnName), x);
}
@Override
public void updateShort(String columnName, short x) throws SQLException {
updateShort(getColIdxByName(columnName), x);
}
@Override
public void updateInt(String columnName, int x) throws SQLException {
updateInt(getColIdxByName(columnName), x);
}
@Override
public void updateLong(String columnName, long x) throws SQLException {
updateLong(getColIdxByName(columnName), x);
}
@Override
public void updateFloat(String columnName, float x) throws SQLException {
updateFloat(getColIdxByName(columnName), x);
}
@Override
public void updateDouble(String columnName, double x) throws SQLException {
updateDouble(getColIdxByName(columnName), x);
}
@Override
public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {
updateBigDecimal(getColIdxByName(columnName), x);
}
@Override
public void updateString(String columnName, String x) throws SQLException {
updateString(getColIdxByName(columnName), x);
}
@Override
public void updateBytes(String columnName, byte x[]) throws SQLException {
updateBytes(getColIdxByName(columnName), x);
}
@Override
public void updateDate(String columnName, java.sql.Date x) throws SQLException {
updateDate(getColIdxByName(columnName), x);
}
@Override
public void updateTime(String columnName, java.sql.Time x) throws SQLException {
updateTime(getColIdxByName(columnName), x);
}
@Override
public void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException {
updateTimestamp(getColIdxByName(columnName), x);
}
@Override
public void updateAsciiStream(String columnName, java.io.InputStream x, int length) throws SQLException {
updateAsciiStream(getColIdxByName(columnName), x, length);
}
@Override
public void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException {
updateBinaryStream(getColIdxByName(columnName), x, length);
}
@Override
public void updateCharacterStream(String columnName, java.io.Reader reader, int length) throws SQLException {
updateCharacterStream(getColIdxByName(columnName), reader, length);
}
@Override
public void updateObject(String columnName, Object x, int scale) throws SQLException {
updateObject(getColIdxByName(columnName), x, scale);
}
@Override
public void updateObject(String columnName, Object x) throws SQLException {
updateObject(getColIdxByName(columnName), x);
}
@Override
public Object getObject(String columnName, java.util.Map<String, Class<?>> map) throws SQLException {
return getObject(getColIdxByName(columnName), map);
}
@Override
public Ref getRef(String colName) throws SQLException {
return getRef(getColIdxByName(colName));
}
@Override
public Blob getBlob(String colName) throws SQLException {
return getBlob(getColIdxByName(colName));
}
@Override
public Clob getClob(String colName) throws SQLException {
return getClob(getColIdxByName(colName));
}
@Override
public Array getArray(String colName) throws SQLException {
return getArray(getColIdxByName(colName));
}
@Override
public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException {
return getDate(getColIdxByName(columnName), cal);
}
@Override
public java.sql.Time getTime(String columnName, Calendar cal) throws SQLException {
return getTime(getColIdxByName(columnName), cal);
}
@Override
public java.sql.Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {
return getTimestamp(getColIdxByName(columnName), cal);
}
@Override
public void updateRef(String columnName, java.sql.Ref ref) throws SQLException {
updateRef(getColIdxByName(columnName), ref);
}
@Override
public void updateClob(String columnName, Clob c) throws SQLException {
updateClob(getColIdxByName(columnName), c);
}
@Override
public void updateBlob(String columnName, Blob b) throws SQLException {
updateBlob(getColIdxByName(columnName), b);
}
@Override
public void updateArray(String columnName, Array a) throws SQLException {
updateArray(getColIdxByName(columnName), a);
}
@Override
public java.net.URL getURL(String columnName) throws SQLException {
return getURL(getColIdxByName(columnName));
}
}
您还可以查看org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet
,其中还说:
注意:从JDBC
4.0开始,已经阐明,任何使用String来标识列的方法都应使用列标签。列标签是使用SQL查询字符串中的ALIAS关键字分配的。当查询不使用ALIAS时,默认标签为列名。大多数JDBC
ResultSet实现都遵循这种新模式,但是有一些例外,例如com.sun.rowset.CachedRowSetImpl类仅使用列名,而忽略任何列标签。从Spring
3.0.5开始,ResultSetWrappingSqlRowSet
它将列标签转换为正确的列索引,以更好地支持,com.sun.rowset.CachedRowSetImpl
这是使用JdbcTemplate
RowSet时使用的默认实现。
问题内容: 我正在为我的应用程序使用Hibernate 3.2.5。 我有一张桌子和一张桌子。 部门java 员工.java HBM映射文件 以下是本机SQL的代码: 我得到了例外: 当我直接在数据库中运行查询时,我会得到正确的输出,但是在hibernate状态下,它给出的是。我已经确认列名仅是正确的。 请让我知道如何解决此问题。 问题答案: 您的映射中包含以下内容: 但是您的sql 和之间没有这
问题内容: JPA 2.0(Hibernate 4.2.4.Final/Spring 3.2.8.Release)/ Mysql 5.6 对于管理实体E w /自动生成的主键,例如 出于传统原因,foo需要等于:{id}:。例如,如果id为204,则foo将为“:204:”,因此在事务中发生这种情况是可行的 有没有一种更好的方法来计算值取决于生成的ID的派生列?没有上述技巧,即在持久化之后直接更新
问题内容: 我有一个JSP文件,我将在Eclipse,Maven和Tomcat的帮助下将其部署在Java项目中。我还有一些其他的JSP文件与此文件几乎相同,尽管它们运行不同的操作。无论如何,当我转到页面时,我已经给出了: Bug是一个自定义类,可以接受结果集--并执行以下操作: 其中BUG_ID,PERSON_OPENED_BY,PERSON_ASSIGNED_TO,TITLE和PROJECT_I
本文向大家介绍ASP.NET批量操作基于原生html标签的无序列表的三种方法,包括了ASP.NET批量操作基于原生html标签的无序列表的三种方法的使用技巧和注意事项,需要的朋友参考一下 在网页开发中,经常要用到无序列表。事实上在符合W3C标准的div+css布局中,无序列表被大量使用,ASP.NET虽然内置了BulletedList控件,用于创建和操作无序列表,但感觉不太好用。本篇介绍服务器端A
问题内容: 这是logcat: 与之关联的行是: 可能是什么问题呢?创建数据库就好了。您还需要查看其他代码吗? 更新: 我非常确定此列存在。我用这个查询数据库: 在LogCat中: 因此该列确实存在。 问题答案: 我发现了一个奇怪的解决方案。在中。你所要做的:
我用java编写了一个简单的程序,它创建到Oracle数据库的连接并执行更新查询。 查询成功执行,但如果更新查询包含以“F”开头的列,则抛出异常 “java.sql.SQLSyntaxErrorException:ORA-00904:“F”:无效标识符”。 如果我删除以“F”开头的列,那么< code > prepare statement . getparametermetadata()将正确执