回答

收藏

Oracle SQL-如何使用JSP调用ODCI流水线函数

技术问答 技术问答 240 人阅读 | 0 人回复 | 2023-09-12

以下是https://docs.oracle.com/cd/B28359_01/appdev.111/b28425/pipelined_example.htm#CHDHDHEE的确切实现  i- x, @0 L! J

7 z( x1 d4 V+ ]2 a假设我们具有以下表定义:9 W; j" A* m# q) a, v$ ?2 a* q
CREATE TABLE StockTable (
1 s* J% U: i. Z5 O# u0 l  ticker VARCHAR(4),
0 k9 G8 e0 A- C" o+ a  openprice NUMBER,
+ B& q* ~- F" m9 I  closeprice NUMBER/ S' {( t) `! }* j+ T. J; B3 o
);$ ~' d, m% s2 U- h& V6 Z9 h; [5 o
然后,我们得到以下类型(作为对象的基本类型和作为表的类型):
* ?' P/ w7 O4 S5 U+ n& a- XCREATE TYPE TickerType AS OBJECT
! D& V+ n( Z6 T5 v: F: ?(
8 [8 _* u, q# g2 Q  ticker VARCHAR2(4),1 p/ Y1 H4 W& ^7 W/ t
  PriceType VARCHAR2(1),/ |7 z: q, e  Y% n& h1 d
   price NUMBER1 @: t* e6 H; `1 s' y" x7 }: s
);8 f8 r: s7 j, {6 ~
/
! @4 T- Q, O7 w2 n# Q4 {CREATE TYPE TickerTypeSet AS TABLE OF TickerType;8 E7 @) [! O) `7 n) a) T" K, C3 K
此外,我们还定义了ODCI类型及其在数据库中的SQL和Java存储过程中的实现:
5 J5 Z8 r2 O; S! W/ E6 H/ OSQL:- Z; x$ d2 Q! H% X8 q
CREATE OR REPLACE TYPE StockPivotImpl AS OBJECT0 ?8 A- G* E+ h; Q  D. r
(/ E/ E6 ^7 U4 H  g
  key INTEGER,1 s) S$ T2 p+ e/ v- J5 n
  STATIC FUNCTION ODCITableStart(sctx OUT StockPivotImpl, cur SYS_REFCURSOR)) a$ {+ N# K! W: g- s! {) ]
    RETURN NUMBER7 l/ ]1 w& T# V) Z9 y
    AS LANGUAGE JAVA
4 ^8 p1 [: M( D8 X& Z. r, a: @    NAME 'StockPivotImpl.ODCITableStart(oracle.sql.STRUCT[], java.sql.ResultSet) return java.math.BigDecimal',
& z2 p' s( S4 h, ~% V  MEMBER FUNCTION ODCITableFetch(self IN OUT StockPivotImpl, nrows IN NUMBER,
& f# {0 c2 Z) E  K                                 outSet OUT TickerTypeSet) RETURN NUMBER' ^3 k" O* B) a% C# i& `6 E
    AS LANGUAGE JAVA
  ~# @; B/ C( @; |    NAME 'StockPivotImpl.ODCITableFetch(java.math.BigDecimal, oracle.sql.ARRAY[]) return java.math.BigDecimal',' k# \8 S3 Q/ _2 V. Z
  MEMBER FUNCTION ODCITableClose(self IN StockPivotImpl) RETURN NUMBER
  \# Z  x" s+ U' v8 m$ h; k    AS LANGUAGE JAVA
8 t% O4 f# a8 {0 N' r" S# B. S( e    NAME 'StockPivotImpl.ODCITableClose() return java.math.BigDecimal'
' O5 ~& h0 d8 ~' u: j# n1 X);
% w9 C/ X9 n/ P/ @' @/
% J3 a& p( X; d0 Y0 c$ G$ dJava存储过程:" w$ H- [3 w, ?1 h4 q( s
import java.io.*;* b6 ?$ E1 h) w! g6 O( _+ d0 z5 E
import java.util.*;
+ l4 ~$ P1 H# Simport oracle.sql.*;, j$ l7 ]: g3 k1 T( T$ D! g
import java.sql.*;
: p. r3 G4 K  f- b/ X  j0 b; D8 Aimport java.math.BigDecimal;; [0 k: F" K1 ?
import oracle.CartridgeServices.*;+ n8 y5 F& @# e- U) i
// stored context type
1 l8 V: p7 F( m/ ]public class StoredCtx7 V% p# m; E& U! f* w$ X
{& {$ m2 d- [4 Y$ \8 a* P
  ResultSet rset;
0 O4 S5 V% `" l. v; c4 T0 s  public StoredCtx(ResultSet rs) { rset=rs; }: I( w) D" f7 K* m- C* i
}) ^& N& M8 L; G& E$ O! l: X
// implementation type+ h% `( K2 Q1 c" s4 N' H
public class StockPivotImpl implements SQLData
" P8 k- Z! u3 X. A{- {4 E) d% I/ Y- P0 O: |
  private BigDecimal key;9 [$ X; g9 B2 W& s1 t1 C6 m
  final static BigDecimal SUCCESS = new BigDecimal(0);( o6 s3 l+ s, c  z6 L2 ~, w
  final static BigDecimal ERROR = new BigDecimal(1);
9 |" m7 F0 M! h; ?5 m& ]9 _% |  // Implement SQLData interface.
" ~# z5 K) p: M2 w& L  String sql_type;# x3 m0 `* F7 }7 W
  public String getSQLTypeName() throws SQLException # x( c3 k5 H: n3 _0 A
  {. _; ]$ I" c) N/ H, w7 r
    return sql_type;" D  i/ T' u5 ?/ G
  }
- ]0 K, J' h2 k, T% U  public void readSQL(SQLInput stream, String typeName) throws SQLException # R% q6 `) ^2 d, w. W" D4 Z
  {
0 o! d1 u, W3 o$ V9 ]" o& G    sql_type = typeName;* y2 l4 @" l# k, x# h6 Y, ?- u8 Z" |
    key = stream.readBigDecimal();
- n4 v  A* f# z: ~3 s  }
! g/ }; _9 E1 e$ j# {, n7 K  public void writeSQL(SQLOutput stream) throws SQLException
1 B3 L2 }3 t  q% F  {. p9 Y+ e7 O% ~  C
    stream.writeBigDecimal(key);' i* S, i$ {3 a% y* o; e* M1 T
  }* `) c. d0 P& O+ e
  // type methods implementing ODCITable interface1 D- S0 `2 e& y4 m* J; `6 L" E+ {3 \
  static public BigDecimal ODCITableStart(STRUCT[] sctx,ResultSet rset)5 i# U) s8 r/ `7 |
    throws SQLException
) p$ s1 m  i. Z0 H! Y  {- {- @- U0 p. V! L4 W+ {
    Connection conn = DriverManager.getConnection("jdbc:default:connection:");
0 S8 x) e$ S- O6 B4 x  Z& X( s! l    // create a stored context and store the result set in it* y8 t/ h- J% k7 ^
    StoredCtx ctx=new StoredCtx(rset);# n: s& A3 |& }% ^; B+ V
    // register stored context with cartridge services7 F. j4 U0 m3 G
    int key;6 G8 Y8 z7 g6 _1 b
    try {; k4 @! [  T$ d% o% Q) E4 l( D6 g
      key = ContextManager.setContext(ctx);
. k6 _+ H% d, Y7 c: r" m! J2 ?9 }    } catch (CountException ce) {
; V4 q7 }- Z5 u* a% e$ C3 S      return ERROR;$ j+ U' R8 \0 t. j1 V3 M$ @
    }$ ~& }+ d+ ~6 `3 u% J
    // create a StockPivotImpl instance and store the key in it
7 s  B$ c# a+ w# F2 H9 X    Object[] impAttr = new Object[1];; I1 k9 R$ `. l  z  w. V
    impAttr[0] = new BigDecimal(key); + M( w8 o, n7 A  w5 ?$ k8 T
    StructDescriptor sd = new StructDescriptor("STOCKPIVOTIMPL",conn);% B$ `% E0 n) [0 w. v3 |  H0 b! [
    sctx[0] = new STRUCT(sd,conn,impAttr);4 z) @4 T$ P- R& x: f
    return SUCCESS;
* `: x$ _8 ?$ h; N0 H2 u* N  }* f& ~% n0 T1 C& G4 h% z6 D
  public BigDecimal ODCITableFetch(BigDecimal nrows, ARRAY[] outSet)& |4 @+ M  C- [0 H0 h5 M( s
    throws SQLException 3 o; `6 W( U  U$ I, i  D4 A3 C& S2 U
  {
. l8 I  Y$ M) k& R; t    Connection conn = DriverManager.getConnection("jdbc:default:connection:");; V8 H+ q% S& @
    // retrieve stored context using the key  x1 E. M: `( h$ l
    StoredCtx ctx;
6 _* ~( k! \% v2 d% J* V1 H8 m7 z) L, x    try {' U! x4 C# q' R( d0 D# G. A8 v
      ctx=(StoredCtx)ContextManager.getContext(key.intValue());
& L$ y4 y7 Q* M' l- E    } catch (InvalidKeyException ik ) {' j/ X6 [0 d2 F/ e1 J+ P
      return ERROR;7 L' y# ?1 c* z, a2 E8 [) h
    }
' Q) }3 B  l6 {( J    // get the nrows parameter, but return up to 10 rows
+ U- i- [% H) S2 |0 N( g    int nrowsval = nrows.intValue();
+ R* i( ]; z2 x, ]7 ^    if (nrowsval>10) nrowsval=10;/ k; i; `* u! ^  @: F
    // create a vector for the fetched rows' A9 `$ O. G- p2 G5 a% F! e  l
    Vector v = new Vector(nrowsval);
$ E: t  E  k' \7 T1 O" I# U    int i=0;
5 t7 w# U+ v, m; P! ^5 {  t    StructDescriptor outDesc =
& L- h7 b# q0 p5 u' o      StructDescriptor.createDescriptor("TICKERTYPE", conn);
8 U/ H% f! l; Q9 C: U+ T    Object[] out_attr = new Object[3];7 \1 E7 \' K  \4 p7 d( C1 R
    while(nrowsval>0 && ctx.rset.next()){' [) l; c, l5 S' }
      out_attr[0] = (Object)ctx.rset.getString(1);$ H0 E. @0 q; M5 g  m1 q$ P* p: v  B
      out_attr[1] = (Object)new String("O");9 I* W# x, Q" ^$ B; ]9 k! w
      out_attr[2] = (Object)new BigDecimal(ctx.rset.getFloat(2));
0 l% Z1 K2 k# P0 o# ]$ N8 z      v.add((Object)new STRUCT(outDesc, conn, out_attr));. J1 ?2 K0 b  V- c6 ^* Y
      out_attr[1] = (Object)new String("C");* [# V9 F4 d7 b5 R# y
      out_attr[2] = (Object)new BigDecimal(ctx.rset.getFloat(3));
% j. _  A3 S+ V5 k) D" _) v/ }! t" A      v.add((Object)new STRUCT(outDesc, conn, out_attr));
/ t' ~$ \* a; F: U: n      i+=2;; Z3 E) h+ X8 W3 \
      nrowsval-=2;' X. N4 u& [! h  B( Y7 k
    }6 D! `  Y5 @4 T9 L7 E, ?. j
    // return if no rows found
; a+ |; i' S& q' F+ S% z    if(i==0) return SUCCESS;
* N& _  e/ V0 k7 ?    // create the output ARRAY using the vector  b* @1 B! G9 Z. Z
    Object out_arr[] = v.toArray();
/ v& G5 f' [8 `/ S4 [7 q: M5 ^    ArrayDescriptor ad = new ArrayDescriptor("TICKERTYPESET",conn);
2 h9 ^5 _) U- s) v7 }    outSet[0] = new ARRAY(ad,conn,out_arr);+ A! c+ H5 n  A- N  e
    return SUCCESS;2 i1 ?& s5 Q) o: B1 [; T( q) I
  }; o' n  y2 ~. b$ ?3 D9 X' h
  public BigDecimal ODCITableClose() throws SQLException {
+ o% L/ m! t- X$ t    // retrieve stored context using the key, and remove from ContextManager
! F/ }7 {) B9 o! W" S- B% H    StoredCtx ctx;
( `$ O9 E. J9 a; [7 S+ u    try {$ E. Q6 M9 s7 b0 X" g
      ctx=(StoredCtx)ContextManager.clearContext(key.intValue());& f! n4 g- c' T' [5 B
    } catch (InvalidKeyException ik ) {$ a: W: j% d' C5 S6 ]* k0 C
      return ERROR;
  X  w: M0 P! O) M2 J# _1 h4 {    }
' f7 T1 \9 L9 u6 I& D    // close the result set
7 Q+ @; [! j: ^  C, Y: e    Statement stmt = ctx.rset.getStatement();9 `" n  s7 }/ }3 r7 q2 Z
    ctx.rset.close();9 }4 A3 ]* `% m$ V; c& d
    if(stmt!=null) stmt.close();' Q7 Q# @7 b6 T, E
    return SUCCESS;
& J8 i/ G0 r" P1 e% l$ c- [  }
# a& o: U* H& q8 z}+ \8 u( }* C/ {0 q/ W
所有这些之后,为了拥有可用于创建上述表类型的表的 流水线函数 ,我们需要具有 ref游标流水线函数本身
  P$ u# k+ U: P$ [# u; D. S。我已将ref游标放入包中。1 ~# p( d8 w; D8 |
-- Define the ref cursor type
( Q' {" z: n3 [4 _  CREATE OR REPLACE PACKAGE refcur_pkg IS. b/ X7 J/ q" V$ E% u
    TYPE refcur_t IS REF CURSOR RETURN StockTable%ROWTYPE;
+ [/ G* S3 i2 `9 O) W, I  END refcur_pkg;, g. o( S6 A' F
/+ _+ n* v1 }! O  r
  -- Create table function+ n8 p  X! J( y; ]3 C
  CREATE OR REPLACE FUNCTION StockPivot(p refcur_pkg.refcur_t) RETURN TickerTypeSet9 L8 U( H8 F# y1 L
  PIPELINED USING StockPivotImpl;, z) b5 ]' N0 @- ?
/
  \. u# Z. D) B7 H! r我的问题是,如何调用StockPivot函数以执行JSP并显示所提到类型的表。! q7 U+ V$ \6 g5 v; P
我期望从模拟表的简单选择中得到一个结果:
% T- _' `* S/ p3 k-----------------------------
& l, e& n, t3 D7 K2 d7 K|  column1 |  column2 | ... |  Q2 O+ Q3 H; b5 F( R0 P" j
|---------------------------|
: o6 q/ x, k  @3 q| row_data1| row_data2| ... |0 ~/ w9 O3 |( W; @) l
| --------------------------|1 T  d: l6 n4 P
|___________________________|4 ]. Q, S6 M/ R: m+ K- I2 E
我试图这样调用该函数,但是由于 明显的 原因(我们需要使用ref游标作为参数),它无法正常工作:0 ^) `8 c2 U. [3 |
SELECT * FROM TABLE(StockPivot());
! [: o( H' E2 K" F; ?8 I7 o先感谢您。7 ~7 U- M$ n/ K2 _8 \
               
+ |  C  }2 ~9 c7 Q* @解决方案:
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则