回答

收藏

基于列标签的CachedRowSetImpl getString会抛出“无效列名”。

技术问答 技术问答 71 人阅读 | 0 人回复 | 2023-09-13

当我执行以下代码时,一切都很好:, T7 |* o* k. `/ i
ResultSet rs = con.prepareStatement("SELECT r.UID AS R FROM r").executeQuery();
! `2 Y* I8 z' t& o3 u# R% T5 B0 sSystem.out.println(rs.getMetaData().getColumnLabel(1));9 f+ z3 N) n* }6 g4 l
rs.next();" e; g) h' \7 x) k4 B2 H% N1 r( l7 {
System.out.println(rs.getString("R"));! G' E, L" ^% ]
结果是:
5 d  S4 i) u& M- r8 c! l) ZR
& ~" {9 K8 ]% x# u0 `% w4 z236 |% [6 i( T  S) I, \
但是当我执行以下代码时:
6 ?6 y/ s, d# Q+ S2 t5 S& fResultSet rs = con.prepareStatement("SELECT r.UID AS R FROM r").executeQuery();
5 C) r' y; _) LCachedRowSetImpl rslt = new CachedRowSetImpl();8 j# s% a4 E* D6 _; g0 H' D
rslt.populate(rs);
. K0 l0 o! ?, D1 r% d) x+ dSystem.out.println(rslt.getMetaData().getColumnLabel(1));: _3 C8 k5 S$ Z. o" N' |" A
rslt.next();+ V/ J: y- N% f
System.out.println(rslt.getString("R"));0 q9 N8 ~& P0 N2 E( H
结果是:
" b/ D# x: Z/ N. ]R  n0 Y0 B- f# R- a
java.sql.SQLException: Invalid column name, F* C  P9 y. a8 c. p2 v4 `: ~
为什么在这里抛出异常?
; H& q. o0 n8 d4 d# t  C                - Y/ Q4 q; ]) w" u3 S0 ?; _3 j! x
解决方案:
* M: l  X1 I0 q" y, n: y' y               
$ S* C7 z8 L/ b: J+ K+ u9 c
9 r9 w( c0 t- u4 W3 R1 P4 O- b& C! D$ r5 S: h
                问题是,参考实现CachedRowSet(com.sun.rowset.CachedRowSetImpl)包含一个错误:当您通过名称检索列,它使用的columnName,而: s2 o# [9 \- a0 c, Y$ S  q
不是
8 z( j# L% _% B. C在columnLabel,为此逆着它使用JDBC规范的其余部分columnLabel检索值。此错误使得不可能通过来从行集中检索值columnLabel。
, C2 `, e; r, ]" d# HOracle的错误是http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7046875,但是(感到惊讶)他们使该错误无法供公众查看。
7 N7 n) M8 H# o% ?$ b6 U  A7 G有两种可能的解决方法。一种是检查驱动程序是否提供了一个属性,以使该ResultSetMetaData.getColumnName(..)方法也返回该columnLabel值,第二种解决方法是创建的子类CachedRowSetImpl(不幸的是,它需要很多重写方法)。3 T5 R% F1 ]  x4 T( U' ?
以下版本是从此消息复制的:http : //tech.groups.yahoo.com/group/Firebird-
. u! j' X+ S+ m/ l. rJava/message/107152 X: O7 ]8 Q/ F1 t# o& i. p4 S
import java.math.BigDecimal;
/ R, `& w0 }8 X0 O. Z9 @import java.sql.Array;2 f# T* @4 d9 Z3 w5 e8 {. [
import java.sql.Blob;
" M! f7 k+ ^1 {2 P( vimport java.sql.Clob;% I! A$ J; r# M; J$ t, }5 T1 a
import java.sql.Ref;
! r! V: F! {4 t2 D1 D  v1 bimport java.sql.SQLException;/ u" ]9 O( b- i7 ?& B8 t
import java.util.Calendar;4 j5 K6 g) s" i% p
import java.util.Collection;5 u2 l( o* `+ Z- ~  L6 b9 j& k
import java.util.Hashtable;
' ]. |9 A9 A; i- o6 limport javax.sql.rowset.RowSetMetaDataImpl;! B8 ~2 B5 b9 \% S5 o
import com.sun.rowset.CachedRowSetImpl;
" r; O, L4 I- o& npublic class FixedCachedRowSetImpl extends CachedRowSetImpl {
* e* J, ^6 B4 s    private static final long serialVersionUID = -9067504047398250113L;. d" t0 N6 u* J4 f" s: A5 ~0 J
    private RowSetMetaDataImpl RowSetMD;
: \1 x7 S+ t1 l/ O9 x# U" E) y4 W0 w    public FixedCachedRowSetImpl() throws SQLException {
+ _) {/ z$ o/ X& t        super();
4 G! H, ?% }- ?; l6 X    }% b7 d8 |5 C4 S- [4 I+ Q
    public FixedCachedRowSetImpl(Hashtable env) throws SQLException {
: {( f0 `1 {; f. J: u. A        super(env);/ V# X! N7 \% \, W  W
    }( a+ s' U' b4 _2 F  S5 c
    private int getColIdxByName(String name) throws SQLException {2 m9 {, M+ n0 s, X; J
        RowSetMD = (RowSetMetaDataImpl) this.getMetaData();
+ O' M- U+ a& Y& P3 D$ G) \4 s! t        int cols = RowSetMD.getColumnCount();2 ]2 j6 Z7 g$ D0 D9 }1 s; l' }
        for (int i = 1; i  toCollection(String column) throws SQLException {
! [" I9 [' J1 x+ @8 b; Q! @, w0 o        return toCollection(getColIdxByName(column));
- i+ P- e; z/ X3 F& g) v9 E    }( E& {! Y6 O/ B  X
    @Override' o; x/ g0 ]* p7 T
    public String getString(String columnName) throws SQLException {
5 W3 S: x, J$ Y, C/ y- j        return getString(getColIdxByName(columnName));5 E' F  r8 G$ }
    }
& A( w4 f8 i7 o" T2 H3 Q    @Override
, X9 D* s% \6 X9 r# U, y    public boolean getBoolean(String columnName) throws SQLException {3 O+ \1 n6 _8 Z" {% I. x
        return getBoolean(getColIdxByName(columnName));
1 {; U$ X4 r$ z1 u: `: T% K9 O    }
: N  r; }# x$ X+ J3 T% ]4 o    @Override
. L4 A* D2 u7 P0 i$ [. l& A    public byte getByte(String columnName) throws SQLException {( h1 r& P; a5 g
        return getByte(getColIdxByName(columnName));) |$ M5 T. ^# b& F' E* t' X' ~$ P
    }+ N/ A8 `* p. ^. K1 q9 a
    @Override
$ s" B, Y% Z1 B/ w& O    public short getShort(String columnName) throws SQLException {
' w; ]6 Q" e% E        return getShort(getColIdxByName(columnName));" T8 }0 U6 k6 x$ h6 k. c! H- b- V" C
    }. t9 F0 G7 \% b- f& M* k
    @Override
3 S' J5 a  L: c( o    public int getInt(String columnName) throws SQLException {
' o2 U% g! ^% K& I6 u+ I        return getInt(getColIdxByName(columnName));! m4 f. I) L' b8 e' B! D+ u4 m
    }
* J' ^/ X9 e- g7 ~5 z    @Override
" @" b; {# l' Y# v  Q# ?6 _1 x    public long getLong(String columnName) throws SQLException {# w! q" ?& G, n5 o
        return getLong(getColIdxByName(columnName));9 A5 V5 S- r8 `/ |! e: Z3 {& r5 B
    }7 U& B* M5 d( R1 }; U
    @Override; G4 w! ^- N* C" P3 n& ~5 L6 S
    public float getFloat(String columnName) throws SQLException {" [5 c5 b5 F, x5 |- M% t
        return getFloat(getColIdxByName(columnName));- c) t, ^: s5 C. v3 ~
    }5 @' l  c7 l* ^$ t$ H+ P: ]" |
    @Override
* l6 ?+ V- j* n' ?    public double getDouble(String columnName) throws SQLException {
! u1 `# Y: L5 J        return getDouble(getColIdxByName(columnName));
8 n! ~3 {. }/ I' n    }
1 z) d, Y& z/ ?" `( F" F0 S    @Override
( }$ |; |- X% u+ [    public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {/ z7 y. o/ H, m# ^% B" o' [5 k; {
        return getBigDecimal(getColIdxByName(columnName), scale);2 q8 D$ j, z+ G9 }7 o
    }9 {. ]3 ~' m# F4 j' e
    @Override8 N+ \8 p8 Z4 g' J
    public byte[] getBytes(String columnName) throws SQLException {
- w1 p1 \/ _9 n/ b6 Y* J4 l        return getBytes(getColIdxByName(columnName));& f1 }! P9 ~1 Z" n* M& t3 t7 {# c; X
    }" P* G, _" r- R0 K/ a2 v1 ~6 t
    @Override
* W& r4 S# b) ]0 J2 r. B9 r$ K    public java.sql.Date getDate(String columnName) throws SQLException {6 ~" ?2 W' [2 `; V  i" d/ V6 ~
        return getDate(getColIdxByName(columnName));; X! U! S& x2 \3 `" `
    }
# O- M2 C/ ~) @    @Override
- r: @- R! H0 `: f9 J    public java.sql.Time getTime(String columnName) throws SQLException {
" k3 w; |3 {2 R/ n% N& s. i        return getTime(getColIdxByName(columnName));+ y- |, O3 T! m& {
    }, w* X' u8 e0 O. e+ l# M4 z2 r2 p
    @Override! M# @/ z% Y8 }' P6 C& g2 I
    public java.sql.Timestamp getTimestamp(String columnName) throws SQLException {
) N! L5 o: y/ v: Y: M! t        return getTimestamp(getColIdxByName(columnName));
5 V$ h: b6 Z1 B$ o8 {( g    }
3 ]$ K' b* C: J- w    @Override
, T' o7 W) b2 Z" d) A/ P    public java.io.InputStream getAsciiStream(String columnName) throws SQLException {2 Y; J, Z5 m; \4 `# M2 f+ Q: a
        return getAsciiStream(getColIdxByName(columnName));
# E4 Y2 \4 F" j3 u- u0 X    }
1 e) D. k7 ~4 U2 `- w    @Override
/ K  `' Y5 ]5 \; a) h9 m- X9 C    public java.io.InputStream getUnicodeStream(String columnName) throws SQLException {/ j$ @) d! b" I9 o9 L& u
        return getUnicodeStream(getColIdxByName(columnName));
4 N/ ^: ~: _2 P, w  a    }- f1 c8 r7 Y. I2 @/ N' W( D) v
    @Override
& N3 p8 d& v( b3 B/ @; G    public java.io.InputStream getBinaryStream(String columnName) throws SQLException {
7 o- h! _0 n% v, [! _4 z        return getBinaryStream(getColIdxByName(columnName));4 c' l; u$ O# E7 G, F! }
    }
& H- N* p" m, [+ J5 u    @Override
6 }, Z3 L# h- [& }5 v    public Object getObject(String columnName) throws SQLException {/ z+ t! R& o, H* j0 N( O/ v3 q+ L# ~8 e
        return getObject(getColIdxByName(columnName));
3 M. j, ?% c4 q# s* q* }* R/ f    }7 Z, i6 Q6 D4 L1 N3 y; j. c) I
    @Override6 Q7 s+ i0 f% s; k0 v
    public int findColumn(String columnName) throws SQLException {
, e7 {5 m2 v# C6 @0 o" q( a        return getColIdxByName(columnName);
9 N* r0 M" S  ~# e, }# v5 X  F    }! c. U! K: i% v- z  r" H
    @Override3 z0 T* z/ I2 ?& `
    public java.io.Reader getCharacterStream(String columnName) throws SQLException {
* N. i3 Z7 _' r        return getCharacterStream(getColIdxByName(columnName));6 W; D" {: X+ n; M
    }
! X3 i2 L" g4 `* ~# Z8 G' T    @Override% u6 B. Y( ~+ z5 R5 B7 P
    public BigDecimal getBigDecimal(String columnName) throws SQLException {% \' O' Y$ A, G3 I7 a
        return getBigDecimal(getColIdxByName(columnName));( _: l2 j& B2 R% @
    }) ^2 Q/ H. t1 d( j# M2 d5 @
    @Override
) p+ C' j  _, m    public boolean columnUpdated(String columnName) throws SQLException {" Q6 D7 b  e" L, a( z# e! @1 y$ B
        return columnUpdated(getColIdxByName(columnName));
. i1 o' A, h: x    }
/ l! C9 R! C- t( p8 x5 o    @Override) }9 q. b0 O* ~* A
    public void updateNull(String columnName) throws SQLException {
) f* S" z, M$ A2 \; d        updateNull(getColIdxByName(columnName));8 U: q* @) b' Y3 n/ ^/ i
    }. O: i1 @! v& Q: ]& e  v
    @Override6 f7 M# H4 k6 C% _
    public void updateBoolean(String columnName, boolean x) throws SQLException {8 |0 K) L$ |9 [2 r! I/ N4 w
        updateBoolean(getColIdxByName(columnName), x);8 i+ X" R5 ?! b8 G
    }7 r) o5 K! u! n! |
    @Override
3 l: L4 B& H9 i" m) ~$ F" ~    public void updateByte(String columnName, byte x) throws SQLException {
: t' \8 \4 y6 ^        updateByte(getColIdxByName(columnName), x);+ t! C# r. ?; e6 d
    }5 m0 [9 R( z" s7 l" _- ~
    @Override
9 V, C* I: G* l( K    public void updateShort(String columnName, short x) throws SQLException {
2 y: N3 u7 U2 x/ |        updateShort(getColIdxByName(columnName), x);
, m. {3 J" N' J3 {    }
( a+ o# F3 e8 O4 I$ y    @Override5 l( @; b6 ?7 y5 {" {4 Z% R0 j
    public void updateInt(String columnName, int x) throws SQLException {
; S/ a" c" @2 ~# a* S2 t  f/ ~6 W        updateInt(getColIdxByName(columnName), x);8 e. Y3 i# X7 I+ l' M
    }
. O$ j# P& \# e0 V7 q+ V    @Override1 X  H! R+ V0 J$ r: |8 ]$ K% L
    public void updateLong(String columnName, long x) throws SQLException {
4 ~0 ]' E1 {0 A$ e; x8 l+ `' n        updateLong(getColIdxByName(columnName), x);
" ]& T# A5 h4 W$ ~( ~+ a2 \, i; B    }) W" V# r- d. n) t
    @Override9 R  a: w% L: a0 Q
    public void updateFloat(String columnName, float x) throws SQLException {
' Z9 i3 }" a/ c+ }" x        updateFloat(getColIdxByName(columnName), x);* D& i* ^9 X1 M+ A4 B: L7 w: D
    }1 d0 ^5 U; H& w- K$ E; Y
    @Override
; j" o- h+ D+ A2 Q- M    public void updateDouble(String columnName, double x) throws SQLException {1 t$ P* j; w/ U% D7 Y$ [
        updateDouble(getColIdxByName(columnName), x);; `8 i- O* z) ~$ V
    }0 S" }( c" f) D# N* I+ \
    @Override
' l& ]  q4 `3 [7 E- b    public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {7 J7 o7 }7 U% ]  A
        updateBigDecimal(getColIdxByName(columnName), x);
/ e1 ^! Z8 f6 Z7 G1 q7 k& N8 m    }
8 {. i8 {3 x! ]1 S    @Override
( U3 d9 e) z) C. r- |+ t    public void updateString(String columnName, String x) throws SQLException {
$ h9 c& |8 P( `* t& h, O        updateString(getColIdxByName(columnName), x);& Y& d9 A  b- |4 @1 L
    }: j) S3 N  y- n( z2 N$ e
    @Override
  e3 M% x; F$ c( ^. J9 b- ]' K    public void updateBytes(String columnName, byte x[]) throws SQLException {. A$ Z+ _5 k+ U- `4 C
        updateBytes(getColIdxByName(columnName), x);
# l# y! G' p( j( s6 }2 Q; l+ c2 |    }( \7 g% ~2 }. v4 B. m0 r0 y
    @Override
' f5 @6 [6 w, R0 k    public void updateDate(String columnName, java.sql.Date x) throws SQLException {
! c8 p$ k$ Q' V! |) [        updateDate(getColIdxByName(columnName), x);* L/ o: L/ t& h* y% t6 u
    }8 W9 l0 X4 y# z- q0 X: \
    @Override/ s9 [) y+ o0 {7 R, W, j
    public void updateTime(String columnName, java.sql.Time x) throws SQLException {
( c4 i6 ^  Y, ]# q% F& Z        updateTime(getColIdxByName(columnName), x);
' h) O) j; C& {9 X  R    }
: K7 C1 ^. v9 I: r0 x    @Override
( Y% w: V" F8 z* a* p    public void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException {4 ~" }# c$ T+ ?2 K0 o
        updateTimestamp(getColIdxByName(columnName), x);! D5 D# I. C" h1 S' ^
    }
$ b7 X6 x1 S" a* w$ n# |    @Override, y, s4 x2 w, j
    public void updateAsciiStream(String columnName, java.io.InputStream x, int length) throws SQLException {8 G, K# s* A/ E
        updateAsciiStream(getColIdxByName(columnName), x, length);1 r9 o$ v) Z6 l& m+ F
    }
: ^5 q3 V- S( u+ d    @Override7 V5 R+ ^0 c, G5 J( {+ s
    public void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException {. \' ~8 L# D7 C( h; M& S
        updateBinaryStream(getColIdxByName(columnName), x, length);9 q2 p) r* z) D- s1 N( H$ l
    }7 `9 R2 d% U1 h" K) S
    @Override
0 F/ b% N# s5 i+ T6 R! P    public void updateCharacterStream(String columnName, java.io.Reader reader, int length) throws SQLException {
* w( V' ?! Y; [9 o: C, b) [7 \; D        updateCharacterStream(getColIdxByName(columnName), reader, length);
" Z2 B" y( j& Q# ]/ J. [1 d0 l    }, j. I: \$ S2 Y  e/ S: Y1 w
    @Override9 G2 j! W1 Y0 z
    public void updateObject(String columnName, Object x, int scale) throws SQLException {# [  ]$ ~) Z  Y' c0 {
        updateObject(getColIdxByName(columnName), x, scale);
# V0 c  s0 i" O8 W4 B* X5 y: T    }
& Z# l, K0 Q/ F  O: G    @Override
9 I, Z7 f; ]7 J! _8 N    public void updateObject(String columnName, Object x) throws SQLException {5 e; n% r( z' d  m  X: V8 K
        updateObject(getColIdxByName(columnName), x);, c- e4 w' |7 ?8 K
    }
7 T' `) @; e% ~9 V/ h8 q/ Y    @Override
- S. H/ a2 L' C% c    public Object getObject(String columnName, java.util.Map> map) throws SQLException {
1 k1 [, H+ G: P+ y1 T+ s% `# k3 {        return getObject(getColIdxByName(columnName), map);
2 w) D) Y) E9 ~" m+ v4 r    }
* `  k2 l$ f: d/ I    @Override
( `( @  K6 v7 u* Z/ Q8 x: T    public Ref getRef(String colName) throws SQLException {
& O( r# r1 H* Y) {+ B! e        return getRef(getColIdxByName(colName));
: T7 c  I) z+ q; Y7 V* M" d) K3 ~    }  t/ M7 W+ U" E1 m6 o! V, e9 v
    @Override' z, Q1 f; _) n! }8 Y
    public Blob getBlob(String colName) throws SQLException {" m5 |- J- j& b& |; }
        return getBlob(getColIdxByName(colName));
% U8 `3 I: c1 t: A8 `$ R# @, f) w    }6 j; x+ U. A3 q. I; Z* M0 i8 {
    @Override3 L; {% m  k- u( A2 ?, D3 Q
    public Clob getClob(String colName) throws SQLException {2 _# S& @. b! m* L
        return getClob(getColIdxByName(colName));
9 t  U7 N& s! B4 F- f5 @; ]    }
0 u( }# M5 a0 z$ f6 L    @Override7 R* g9 L& i) y/ A  v
    public Array getArray(String colName) throws SQLException {
7 T/ k: F7 ~% m  s) e        return getArray(getColIdxByName(colName));$ I" j# b9 n( s2 N
    }( Z# M# T" C( m" k
    @Override
- ]8 {' a$ |7 b0 x    public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException {5 ?& E, `) U2 d
        return getDate(getColIdxByName(columnName), cal);0 |/ p8 ]  P$ t& `6 @, I5 t% z
    }
9 S- G% H- ^4 r( z5 |6 c    @Override" e, b$ c! e1 `" }9 F5 W
    public java.sql.Time getTime(String columnName, Calendar cal) throws SQLException {
/ J8 x$ P5 a5 W+ ]1 L1 M8 a7 g        return getTime(getColIdxByName(columnName), cal);( O% x" V& H' g" U- ~7 Q6 s
    }
! r8 a( p- a  ]    @Override: r4 m: C" _2 A- V8 C
    public java.sql.Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {
" j7 _7 P! H3 U        return getTimestamp(getColIdxByName(columnName), cal);( j( y1 _6 F( ^/ d9 Z+ [0 n
    }; f9 O* d" y+ f" a* C8 O* {. M# a
    @Override
+ a. B; B5 n6 @. P3 |    public void updateRef(String columnName, java.sql.Ref ref) throws SQLException {
  c# z3 j8 J  f7 P, B. r        updateRef(getColIdxByName(columnName), ref);/ s% z, z& t; W( a3 r1 T! c
    }
5 S/ s+ k' \; g" ^& u7 T2 ]6 I( k    @Override2 x1 f  G$ \% t
    public void updateClob(String columnName, Clob c) throws SQLException {2 y9 ~9 x. F4 U" T0 s& W
        updateClob(getColIdxByName(columnName), c);* u% r8 `+ H  j' W% I  n& w0 x
    }% }* L* H8 K9 q9 C) A9 n$ ~( |9 c
    @Override
: |7 |3 H  Y$ v+ T- O    public void updateBlob(String columnName, Blob b) throws SQLException {$ S( j4 h1 L5 L6 R7 T! H
        updateBlob(getColIdxByName(columnName), b);6 w9 m6 Q- B1 p
    }0 p6 A) s) S9 R/ ?. ~2 ?$ S9 x
    @Override
5 G& A  S  ]2 T' t    public void updateArray(String columnName, Array a) throws SQLException {5 w9 x5 c9 e" _4 Z
        updateArray(getColIdxByName(columnName), a);5 m* T( G" Y1 ^6 E  L: r, L) s
    }, w/ N+ j( [( M" \
    @Override
1 W, s) T9 |- M# Z4 s; o    public java.net.URL getURL(String columnName) throws SQLException {& A5 z  [, P- y, W8 y6 w0 B3 i
        return getURL(getColIdxByName(columnName));
9 I: L( c* Z# E1 a    }
3 R% M1 h$ F* S3 |}
0 `; i( g  m3 _6 p" C您还可以查看org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet,其中还说:; r- E0 _: L, B) o, N
) c( z- K/ l! ]  @5 t. l% s( z+ w1 ^
注意:从JDBC
* p2 |' l( c* p8 z' w, a3 C( K4.0开始,已经阐明,任何使用String来标识列的方法都应使用列标签。列标签是使用SQL查询字符串中的ALIAS关键字分配的。当查询不使用ALIAS时,默认标签为列名。大多数JDBC, L# {/ k+ e1 d
ResultSet实现都遵循这种新模式,但是有一些例外,例如com.sun.rowset.CachedRowSetImpl类仅使用列名,而忽略任何列标签。从Spring* P" b1 A7 w, w& @; {" B9 Q8 O: A! q
3.0.5开始,ResultSetWrappingSqlRowSet它将列标签转换为正确的列索引,以更好地支持,com.sun.rowset.CachedRowSetImpl这是使用JdbcTemplateRowSet时使用的默认实现。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则