回答

收藏

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

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

当我执行以下代码时,一切都很好:
+ x: I! a$ Y9 g' q& r) ^9 O) _ResultSet rs = con.prepareStatement("SELECT r.UID AS R FROM r").executeQuery();
* O. s2 ~* Y, h. `  GSystem.out.println(rs.getMetaData().getColumnLabel(1));
% T4 }& |) c* ~0 B4 I% f( O9 xrs.next();; }/ d( M/ d/ Z2 _( u* n
System.out.println(rs.getString("R"));
/ v2 _3 `* F: y- n- s" Y6 g; y: f结果是:
. w; G7 B3 W3 {. ^3 N1 E- pR
1 E- P8 ~' J) u: S3 f23
% n8 v" b) L  O" |) I1 I3 F) {但是当我执行以下代码时:
, [3 T' m( U( \3 E% ]9 M1 MResultSet rs = con.prepareStatement("SELECT r.UID AS R FROM r").executeQuery();
: G1 [, j# w. X; U! f2 Q! XCachedRowSetImpl rslt = new CachedRowSetImpl();
7 j0 C) P$ N7 h4 `rslt.populate(rs);8 L( N& q1 p, s0 z& H
System.out.println(rslt.getMetaData().getColumnLabel(1));1 O6 C, n  R/ r* e  V5 x0 Y$ ~! x
rslt.next();$ N& m# ~4 m4 ^/ J+ E( x) ^) `
System.out.println(rslt.getString("R"));6 u1 s, S# ?% p/ n/ z" l5 P
结果是:" e3 {1 M9 Q8 h, j7 Z4 S
R
; `9 h* y: z9 Q' v! c" w5 A) Gjava.sql.SQLException: Invalid column name6 T5 \2 F/ w9 \
为什么在这里抛出异常?
+ o, o# A1 ~/ _% n: Q* j) Z2 O1 E                8 |) n% R' B2 Q
解决方案:
( r1 L- F* M2 {, C$ A0 i" F                1 h+ R# ^, y3 W
4 O  @8 m, n0 Z
$ m) e9 B, ]0 C! t( Z2 ]  m& {
                问题是,参考实现CachedRowSet(com.sun.rowset.CachedRowSetImpl)包含一个错误:当您通过名称检索列,它使用的columnName,而( E$ S2 K, W1 x5 g
不是
5 c, j# L4 k* }2 i, {在columnLabel,为此逆着它使用JDBC规范的其余部分columnLabel检索值。此错误使得不可能通过来从行集中检索值columnLabel。
3 h, D9 M( u$ y* _1 COracle的错误是http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7046875,但是(感到惊讶)他们使该错误无法供公众查看。4 q0 K2 M$ J% g5 s4 \: _7 m, v- O
有两种可能的解决方法。一种是检查驱动程序是否提供了一个属性,以使该ResultSetMetaData.getColumnName(..)方法也返回该columnLabel值,第二种解决方法是创建的子类CachedRowSetImpl(不幸的是,它需要很多重写方法)。. F( c) W% \( U& |# q" |5 m8 B% Q$ s
以下版本是从此消息复制的:http : //tech.groups.yahoo.com/group/Firebird-
! Q. K8 c+ T" J2 |/ \; QJava/message/10715& z3 U; h: _0 u$ _6 K; b4 E) v6 k$ V
import java.math.BigDecimal;
. B- m2 H& ]7 C6 i. z, {3 K5 {import java.sql.Array;+ h# ]; x) J& a$ t
import java.sql.Blob;
1 J( T, p6 ?* r$ z: _import java.sql.Clob;6 ^- A' l6 `4 E" h% L# Q; Y
import java.sql.Ref;/ h! Z9 U* c1 {$ T1 z- L
import java.sql.SQLException;
* j: z- J# n% R$ c' E- s) o! u- eimport java.util.Calendar;; e! z# O. [, \( P" F! \+ C3 I% z
import java.util.Collection;3 u& v2 \. E. E- a, B
import java.util.Hashtable;
; V" O6 W+ P# e  s) l" @9 ~import javax.sql.rowset.RowSetMetaDataImpl;+ [# n* b# P- z+ T
import com.sun.rowset.CachedRowSetImpl;
0 T6 x/ o2 R6 g& x; c( r$ Ppublic class FixedCachedRowSetImpl extends CachedRowSetImpl {5 R2 \" L# O( R+ ~% o1 t: h$ M# g
    private static final long serialVersionUID = -9067504047398250113L;
" ?& ]1 m' h, j! K# H    private RowSetMetaDataImpl RowSetMD;
6 a! a$ l5 p2 s/ v. ~; B3 p    public FixedCachedRowSetImpl() throws SQLException {
- R/ P: Y6 u# J8 V$ W- L  ]5 d        super();
' @5 M6 `3 h4 W  c( G( L. `7 S# s) a    }
: ~3 ~8 K% h1 i/ ~    public FixedCachedRowSetImpl(Hashtable env) throws SQLException {: b7 b; L4 R4 I. ?4 c
        super(env);
; d* p8 }0 N; J/ w5 ?$ O, P    }0 Q3 C$ R; G5 c6 s" O# |
    private int getColIdxByName(String name) throws SQLException {" G& w/ @, B4 D5 @1 @0 ^# X
        RowSetMD = (RowSetMetaDataImpl) this.getMetaData();
& p4 ^7 O( g- p: ?- J2 Y        int cols = RowSetMD.getColumnCount();
0 v1 `4 g* A. V, [8 o# b: _        for (int i = 1; i  toCollection(String column) throws SQLException {5 A. P) }2 a0 w! p5 m: ]; A5 n
        return toCollection(getColIdxByName(column));
- a$ _* T* J- N    }! g# |  U* o' I" X
    @Override
0 C5 Z/ H% E: K: \2 B( h7 I    public String getString(String columnName) throws SQLException {# i2 J3 d" P: r2 M
        return getString(getColIdxByName(columnName));
& N2 Z$ N# c% x    }, l  w2 u3 e$ U5 R( X& E! V
    @Override
& p& X9 {- E# k( s4 Q    public boolean getBoolean(String columnName) throws SQLException {$ _: a6 I: H) J3 R7 L2 K8 y2 v' R* a
        return getBoolean(getColIdxByName(columnName));$ C* s8 ~4 C3 X
    }( }$ A) R' C0 y
    @Override0 m8 K& W2 M, F9 S3 H- e
    public byte getByte(String columnName) throws SQLException {* R- X# n! o: O8 X, a/ \
        return getByte(getColIdxByName(columnName));1 Z7 L* o8 E3 i- |( S9 D4 P$ {: m
    }
, E7 n) ~& R- Q, r. Q    @Override; v2 l  M' ]5 U
    public short getShort(String columnName) throws SQLException {
/ C- g; l6 n0 P        return getShort(getColIdxByName(columnName));# F- b  n. k* H* Q, V
    }0 y$ g& B0 L5 J& {; t4 {
    @Override8 s# ]5 }# B; u7 x$ A& D0 W
    public int getInt(String columnName) throws SQLException {- \: U1 j7 ^3 E+ [$ ?, a  F
        return getInt(getColIdxByName(columnName));
+ H* O2 U  D3 _& ?; g0 g    }" b9 s+ Q) t# u  n# t' h& [5 T
    @Override
8 u; M, ?: U- ^7 u/ V: _$ x1 J    public long getLong(String columnName) throws SQLException {& O9 W9 a# G; _7 T! Y3 A
        return getLong(getColIdxByName(columnName));$ T; x: g+ y0 `! i% S$ @& |# T6 O
    }; b! L- ^8 B0 H8 a+ b  {; H
    @Override
4 D- f5 n, S  g. v+ q1 Y    public float getFloat(String columnName) throws SQLException {- U7 s  m) O8 y' h/ s
        return getFloat(getColIdxByName(columnName));! A) `  Z* W* ~
    }+ Z$ r% I6 V) F1 `* }. [& {
    @Override
* D; z# c  @/ {( `, [: [5 Y    public double getDouble(String columnName) throws SQLException {
" Y9 C6 O! |3 T. I        return getDouble(getColIdxByName(columnName));4 C7 E" u7 T7 n3 c! l8 |' K
    }! y4 |- r5 f" g. \7 Q
    @Override
( C- ]6 Z% V( H7 K: I) l! |8 D    public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {
- P9 ?' T1 e7 N/ G* |0 f$ L        return getBigDecimal(getColIdxByName(columnName), scale);
3 w: D1 S5 Y8 d0 D3 A; H. f    }
6 ^2 a0 f5 _0 n! F! d. F) p. V( C    @Override9 a% m8 ?1 D$ K* k! M* m  ~6 z6 b
    public byte[] getBytes(String columnName) throws SQLException {) {) w& J( q& @
        return getBytes(getColIdxByName(columnName));
' _3 }0 ]) `: u    }! }/ l& f# h# Y2 r3 n4 i0 \3 Y: y) E
    @Override1 ?) }. s- c6 W( G& E" p8 O7 L
    public java.sql.Date getDate(String columnName) throws SQLException {* r( }+ D) w5 s5 p. p4 w" q
        return getDate(getColIdxByName(columnName));
( T) J% U( q# f! _    }
0 t$ B, Y2 E* E    @Override, |- a/ q/ F* h* e
    public java.sql.Time getTime(String columnName) throws SQLException {9 e0 G3 f; {0 U8 F
        return getTime(getColIdxByName(columnName));
) A* b5 N! ~, G% T% f2 u    }
8 C6 E: v2 o1 T; X7 C+ z4 O( m    @Override5 S/ h# g+ Z1 o8 g) F8 k
    public java.sql.Timestamp getTimestamp(String columnName) throws SQLException {
  f4 b& k9 j* i        return getTimestamp(getColIdxByName(columnName));
' V6 S- f% s' l2 V( X* r    }# W# v6 F; S! u( {1 }4 q9 h# a
    @Override, [# f. X3 `' ~& d7 S) J
    public java.io.InputStream getAsciiStream(String columnName) throws SQLException {0 B: l6 c- ~5 x3 d5 b. e
        return getAsciiStream(getColIdxByName(columnName));6 W, j% x3 c6 O; h: B% A
    }0 Y) G- m; z8 X; O1 A. P5 a
    @Override9 y0 j. l1 K! N9 O4 W
    public java.io.InputStream getUnicodeStream(String columnName) throws SQLException {
; @7 s3 v! x, s2 u$ L0 }. ~        return getUnicodeStream(getColIdxByName(columnName));/ K5 V7 [- F$ G/ |
    }- A1 N+ Y: S( |9 K
    @Override
+ A, r4 G  w* P  b9 i' O    public java.io.InputStream getBinaryStream(String columnName) throws SQLException {
: M0 Z9 X  v$ ^        return getBinaryStream(getColIdxByName(columnName));
& L4 B8 q7 x5 x" x6 N  r9 O# T  y    }$ j7 ]- y, |3 }+ k, |  q
    @Override1 W* f  Z# r+ _) z) b. X. I1 ^3 d
    public Object getObject(String columnName) throws SQLException {
# Y" S, A5 a9 t# O% M0 k+ w        return getObject(getColIdxByName(columnName));
2 p% \" `, Q6 p# f4 i9 B! z    }1 L& Y2 Y% Q7 n6 z
    @Override
% p3 m; {8 h7 r5 ^6 ~2 t    public int findColumn(String columnName) throws SQLException {% v  ~9 D- {8 e; _4 F
        return getColIdxByName(columnName);
$ k" }" x, |. x( }    }
- S* W) t# O6 j8 u    @Override
2 g& L# {3 g! t    public java.io.Reader getCharacterStream(String columnName) throws SQLException {; R( Z+ s8 k* D0 \- \
        return getCharacterStream(getColIdxByName(columnName));$ N' }( U* _# ?, z
    }
( c: d& v: K6 [$ y    @Override6 ~2 @* [4 z6 K, _& t4 n( j2 X
    public BigDecimal getBigDecimal(String columnName) throws SQLException {, _9 E7 S3 g( O$ s% x2 o: U; K
        return getBigDecimal(getColIdxByName(columnName));7 K! t7 c4 n1 C2 Y1 S5 c
    }9 g; r/ \! }- |+ X1 r
    @Override
$ H' H! X- M& J9 I* Q9 \    public boolean columnUpdated(String columnName) throws SQLException {* X* J1 X: t0 e% \
        return columnUpdated(getColIdxByName(columnName));
& @5 ?% O& _2 K    }
4 H4 g' `, j- g* S    @Override
4 ^7 m+ a5 H/ O( Q. _    public void updateNull(String columnName) throws SQLException {4 ~! [6 L# q4 t1 W
        updateNull(getColIdxByName(columnName));
! Z* {4 n% H0 w+ P    }
; R3 O+ g* S% j! N4 M: O* @- |! I    @Override
) x5 B. W2 o  S! L" ]! r    public void updateBoolean(String columnName, boolean x) throws SQLException {
% x5 z- X* E5 A% h$ G- n7 s$ d        updateBoolean(getColIdxByName(columnName), x);
7 o5 M: C8 [3 \3 y    }# d1 s5 ?" J* a: k% z
    @Override2 O) P  ^; |6 M; e) f4 K
    public void updateByte(String columnName, byte x) throws SQLException {
& N& C' p0 Q. {# {8 P& L, N        updateByte(getColIdxByName(columnName), x);1 q: g1 y! J9 ]5 q% Y
    }1 Y% @( `! z  D+ T% g$ A& _0 t
    @Override4 `! T+ _4 B" b: m5 Y$ `
    public void updateShort(String columnName, short x) throws SQLException {5 D" h, y+ }, M, g* c+ `
        updateShort(getColIdxByName(columnName), x);: F2 e5 v0 I" k' W0 a$ e0 W# b/ V
    }* M# M& {2 k9 s: I0 v/ i
    @Override
; a- ~. t5 n- [! j( n    public void updateInt(String columnName, int x) throws SQLException {
) H1 O4 p( c, p4 o3 J; b        updateInt(getColIdxByName(columnName), x);
, @* X- ]& v1 k/ \0 N* \    }; U# {) q9 H( C/ H, ^  ]  n; c7 T
    @Override9 a  T/ a6 A$ W; k; Z, w
    public void updateLong(String columnName, long x) throws SQLException {
( _: u2 X( i7 E( f. C. G) k        updateLong(getColIdxByName(columnName), x);# l' I" }1 l% U* W
    }. y; j4 e1 U$ Q) a. e# u% S1 u
    @Override
6 ~  h+ a8 d; ]. `) k$ r9 |* P  {    public void updateFloat(String columnName, float x) throws SQLException {! Z0 D. J0 L' ^6 ~6 F) |7 Y
        updateFloat(getColIdxByName(columnName), x);
$ S# \# k. d4 S- w    }( p0 y# u+ ]+ t. _; R* ?8 f
    @Override
2 U4 `8 G/ F. j' r# z    public void updateDouble(String columnName, double x) throws SQLException {
3 h& P. j# F6 f' b! [/ m# T9 h        updateDouble(getColIdxByName(columnName), x);
9 K, ~5 [) W& m# F% ?# K    }4 T5 C* b2 K! H: R
    @Override
# ]7 C+ q$ a2 n6 `6 V4 p    public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {
" d, h" M3 N/ \        updateBigDecimal(getColIdxByName(columnName), x);
% _( U7 ?, [4 L  v    }! p0 I% g# I5 B# I
    @Override
0 U/ n* A- Z7 j2 C: ]: r# ^    public void updateString(String columnName, String x) throws SQLException {4 X# F9 V  m: h" z3 u& x9 @! v: Y
        updateString(getColIdxByName(columnName), x);4 F1 M' {/ v& x4 I0 a0 e
    }
  G4 v* u* J- z: ^+ L4 I( w( |    @Override
2 G* A+ h# o) c0 |- L    public void updateBytes(String columnName, byte x[]) throws SQLException {9 F% W/ j, A. _* o* p4 ?. x
        updateBytes(getColIdxByName(columnName), x);
! h6 O2 b  v4 b+ M2 ~% x! D    }
/ M6 {9 g, b' Q1 b! D5 ~; `    @Override; a8 i% F6 [6 p  M  N" N( V
    public void updateDate(String columnName, java.sql.Date x) throws SQLException {
/ y. B/ [9 M# Z' M0 t/ A' D        updateDate(getColIdxByName(columnName), x);, x# J$ L3 H/ E9 I6 E
    }+ f- H  s: l5 i  s& [2 S( o
    @Override
8 @0 b5 _, `9 D    public void updateTime(String columnName, java.sql.Time x) throws SQLException {
3 M/ `" P! o1 ~! A6 h        updateTime(getColIdxByName(columnName), x);9 g4 P) l* [- x* E# n. K
    }
, }  T6 \# q6 e! M    @Override
( t- L7 f9 Y6 }2 c( x3 V    public void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException {0 N  l: O1 f4 [( A
        updateTimestamp(getColIdxByName(columnName), x);1 _) [. E  H' Y" {, v5 k* T
    }
% d: g5 i: `. r5 I& S    @Override
! B5 j" t) }+ J. ]* y    public void updateAsciiStream(String columnName, java.io.InputStream x, int length) throws SQLException {
- U, C, @( X4 V9 g        updateAsciiStream(getColIdxByName(columnName), x, length);( Y# q6 L5 N# o
    }
: n: t2 C2 `2 s# ]4 x8 L! n* A    @Override
0 K  \& m# b3 T4 U    public void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException {
- i5 [9 v% ~; G6 ^' M% ?        updateBinaryStream(getColIdxByName(columnName), x, length);! C- p& Y' B, ?6 P
    }
& x. B/ E; p3 V" S0 O    @Override
) ?- d7 O8 ?! i    public void updateCharacterStream(String columnName, java.io.Reader reader, int length) throws SQLException {/ z; a9 X; ]. L, o8 I2 Q8 E5 m! `
        updateCharacterStream(getColIdxByName(columnName), reader, length);
. e- F: ]# m; a7 Z. ^    }
0 b  Q, P  }* y& [, w! a- [9 T% e    @Override  \* o- }. d$ c9 O" f) c( W7 Y
    public void updateObject(String columnName, Object x, int scale) throws SQLException {
" u& |2 N- [! E- N        updateObject(getColIdxByName(columnName), x, scale);
* J" A6 S. b# Z6 v7 L    }
% E9 G+ N2 Y6 r2 E' s4 M  i    @Override
8 S! q2 S! y1 C1 C    public void updateObject(String columnName, Object x) throws SQLException {: e! t- E, B! v) m6 o
        updateObject(getColIdxByName(columnName), x);
# l& ^6 X2 ]9 }1 ^# G5 T! c/ e    }: G+ a. w/ D- S" q/ c2 l
    @Override
8 i2 Q1 _& |7 r) L2 W3 F8 Q    public Object getObject(String columnName, java.util.Map> map) throws SQLException {
  V3 @9 e; w' C; f9 K, z8 c        return getObject(getColIdxByName(columnName), map);
8 Q$ L  V+ V- A! U    }, d  F% O; w8 F. J
    @Override5 v# j6 J) ~) x; R9 b
    public Ref getRef(String colName) throws SQLException {5 @8 b" e) w4 U6 r( v9 k) W7 G
        return getRef(getColIdxByName(colName));( L+ \2 X0 B5 l& a3 ~
    }
5 r/ W2 i# a. b0 u/ C" [    @Override
3 F; f# O! _* \$ W& L    public Blob getBlob(String colName) throws SQLException {
) b& ], ^+ H3 s" }* c2 F        return getBlob(getColIdxByName(colName));* |, C$ e+ y! u8 p1 [7 z
    }; T3 V9 i  E/ Z4 P1 A/ n# D
    @Override2 h: e: N% q$ R% b
    public Clob getClob(String colName) throws SQLException {0 ]% P! j% t* a0 b+ j/ c, F/ E' |
        return getClob(getColIdxByName(colName));5 X( k% d4 A+ r8 A4 Z
    }
% R$ P( M7 G: S, V' o8 [, P7 Q! m5 v    @Override2 K1 |& y1 R8 f5 Z" B! g
    public Array getArray(String colName) throws SQLException {, h' ^# c  i) }$ w( }6 V  t
        return getArray(getColIdxByName(colName));
( e, w- _1 C- I2 J    }
: F* @0 `* J1 `; E( P3 |# P    @Override
4 J+ m# D% @4 k, O# X6 p! _2 |    public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException {: w+ w! @. h. ?
        return getDate(getColIdxByName(columnName), cal);
' ^; o' r. `$ G4 Q9 X& V0 e7 U9 I    }
( d1 g+ a, E- `4 b; J, g    @Override( \3 L3 k- E& K- n
    public java.sql.Time getTime(String columnName, Calendar cal) throws SQLException {, n0 A! s7 U1 \, \% I" T
        return getTime(getColIdxByName(columnName), cal);
% r, k8 B* Z, p# c. t    }- B. g: M8 x; t% C. i
    @Override: a5 h5 }" C" q% b, Z# q* e" L
    public java.sql.Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {
0 i0 p! F2 g5 Y, `        return getTimestamp(getColIdxByName(columnName), cal);
9 g+ j/ f. y9 j1 q    }
9 X; }) F$ e3 u8 |    @Override+ _; O# s5 N& a  {6 ]1 L
    public void updateRef(String columnName, java.sql.Ref ref) throws SQLException {
4 r2 I2 s- o4 ]1 t; E        updateRef(getColIdxByName(columnName), ref);
, c7 Q) |8 g! k7 w2 w7 s7 e    }
( n4 c: h; V" L    @Override6 Y; C6 T: R# ^1 |) U9 @
    public void updateClob(String columnName, Clob c) throws SQLException {' y, U* B0 g0 U7 ~# a' v' j: d
        updateClob(getColIdxByName(columnName), c);( P! M( X- d/ r; m% U, v! w
    }
9 p* V6 D4 N% |$ i3 K8 ~- X    @Override
( d. n# J& k3 U+ [, q* I" x# E    public void updateBlob(String columnName, Blob b) throws SQLException {
/ r, x  [5 ]# V( {; y        updateBlob(getColIdxByName(columnName), b);
% c9 X; g% B8 `- ^4 S    }8 t$ u( [$ \0 ]) K1 n. A
    @Override
; z3 \/ y* f! @4 A1 C3 a7 a    public void updateArray(String columnName, Array a) throws SQLException {
8 ~; A# S6 h2 ?+ a        updateArray(getColIdxByName(columnName), a);
+ M7 b* |2 m1 I, C    }6 d  C  \$ s" \. e
    @Override) g" u+ `% J7 a1 Q$ N/ F1 \0 a9 _
    public java.net.URL getURL(String columnName) throws SQLException {9 L# Y! p+ T/ G$ x, ^* w$ j" n
        return getURL(getColIdxByName(columnName));
4 Y8 n4 R3 s' Q  L    }2 X! ]4 k  h& [+ x$ X  D
}/ ^& X! Y1 R. X1 F# h
您还可以查看org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet,其中还说:
& k( X& A7 `: D
1 T2 h1 q# y9 H0 P1 d% N0 |注意:从JDBC
2 j& `& r7 j8 b8 r" i: e5 \1 Y4.0开始,已经阐明,任何使用String来标识列的方法都应使用列标签。列标签是使用SQL查询字符串中的ALIAS关键字分配的。当查询不使用ALIAS时,默认标签为列名。大多数JDBC" Z; W% ?3 c/ \& f
ResultSet实现都遵循这种新模式,但是有一些例外,例如com.sun.rowset.CachedRowSetImpl类仅使用列名,而忽略任何列标签。从Spring- p4 f+ W8 e5 z, O8 Z( f9 I
3.0.5开始,ResultSetWrappingSqlRowSet它将列标签转换为正确的列索引,以更好地支持,com.sun.rowset.CachedRowSetImpl这是使用JdbcTemplateRowSet时使用的默认实现。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则