回答

收藏

如何在Oracle作为获取表out参数

技术问答 技术问答 212 人阅读 | 0 人回复 | 2023-09-14

我正在尝试将军oracle过程调用的out参数被迫转换为对象。它不起作用,因为-就我所知-6 w' U; ^# f/ F" k2 a" p
我需要定义一个映射,告诉它如何投射。如果地图是空的或没有正确填充,默认情况下STRUCT类型的Objekt-在我的情况下,这是错误的。5 N8 r$ R1 R+ `/ c& r
我建立了一个示例,应该解释这个问题:7 L: W/ n& r+ I- P8 \  a6 z
-- Procedure in databasePROCEDURE myprocedure (inputParam                IN       VARCHAR2 (4),outputOne                 OUT outputOneSQLTypeoutputTwo                 OUT outputTwoSQLType);-- inside of a packageinside a package mypackage-- first typecreate or replaceTYPE outputOneSQLType IS TABLE OF tableOneExample-- table of typecreate or replaceTYPE tableOneExample AS OBJECT (      somethingOne                 VARCHAR2 (4)   ,somethingTwo        NUMBER (12)//java from hereimport oracle.jdbc.OracleCallableStatement;import oracle.jdbc.OracleTypes;import oracle.jdbc.oracore.OracleTypeADT;import oracle.sql.STRUCT;...oracle.jdbc.driver.OracleConnection oracleConn = (oracle.jdbc.driver.OracleConnection) con.getMetaData().getConnection();final OracleCallableStatement storedProc = (OracleCallableStatement)oracleConn.prepareCall("{call mypackage.myprocedure("                 ":inputParam,utputOne,utputTwo)}");storedProc.setString("inputParam","SomeValue");storedProc.registerOutParameter("outputOne", OracleTypes.STRUCT,"OUTPUTONESQLTYPE");storedProc.registerOutParameter("outputTwo", OracleTypes.STRUCT,"OUTPUTTWOSQLTYPE");storedProc.execute();//So far so good//now I am lost - I need to define the map to get the object? //What should be inside the map?Hashtable newMap = new Hashtable();newMap.put("outputOneSQLType",?????.class);//If the map is empty,it defaults to STRUCT...final STRUCT myObject =  (STRUCT)storedProc.getObject("somethingOne",newMap);// myObject.getBytes() gives me an object... but I cannot cast it to anything由于地图错误,我不能使用以下方法:
2 ^3 b) ]7 c: t( ]- zfinal MyClass myObject =  (MyClass)storedProc.getObject("somethingOne",newMap);如何填写地图?: }6 x3 c/ X3 x7 n
编辑14 W5 N9 }9 ^% A/ c- h) D
oracle数据库中的项目无法更改。我只允许使用它们。
. w; e1 `& Q9 w3 C! ^stmt.registerOutParameter(2,java.sql.Types.ARRAY,"OUTPUTONESQLTYPE");不起作用。因为一旦不使用 OracleTypes.STRUCT,会引起异常。好像在。outputOneSQLType内部有一种类型
4 a& z) x  T; j/ v2 ^+ lOracleTypeCOLLECTION”的对象+ l6 T% ^& U8 r) f) ^
当我尝试; d, Q* e# @) s5 z" f/ p7 Z
    Hashtable newMap = new Hashtable();newMap.put("outputOneSQLType",OracleTypeCOLLECTION.class);final OracleTypeCOLLECTION myObject =  (OracleTypeCOLLECTION)storedProc.getObject("somethingOne",newMap);我有个例外: InstantiationException: oracle.jdbc.oracore.OracleTypeCOLLECTION
4 q. G) b- A' V1 Q1 W% J@DazzaL:我会试着定义一个SQLDATA接口。也许这将是解决方案
9 n: @# I( ^1 O6 c$ {解决方案! a4 V% b% P. b  o' m
[ol]准备好的句子应该类似于 begin package.procedure(…); end;”。而 不是    “ {call package.procedure(…)})( @/ [& f: ^; N7 d% Z% j, I
需要一个SQLData接口。[/ol]@DazzaL:你统治!谢谢。
2 e: M8 q% V) c% ]                                                               
+ I" p% {- E0 R6 e    解决方案:                                                               
0 k0 e4 n& W/ Y: |/ ~: @                                                                你必须定义一个sqldata对象以此映射。
, o( D, M0 u! ^文档:http
+ X/ R; y8 g7 _:: Y7 Z6 _1 c6 j+ y8 c
//docs.oracle.com/cd/E11882_01/java.112/e16548/oraarr.htm#JJDBC28574+ a# M5 ^- m9 }4 y
例如:, e( Q9 G+ h; e* F& W" ^
SQL> create or replace TYPE tableOneExample AS OBJECT ( 2            somethingOne                 VARCHAR2 (4) 3      somethingTwo        NUMBER (12) 4 )Type created.SQL> create or replace TYPE outputOneSQLType IS TABLE OF tableOneExample;  2  /Type created.SQL>SQL> create or replace PROCEDURE myprocedure ( 2   inputParam                IN       VARCHAR2, 3  outputOne                 OUT outputOneSQLType)  4  as  5  begin  6  outputOne  := outputOneSQLType(tableOneExample('a',1),tableOneExample('b,二);  7    end;  8  /Procedure created.我们现在定义它SQLDATA接口:0 x% s; e/ U0 \% [$ Q$ B
String typeName)    throws SQLException {     sql_type = typeName;    attrOne = stream.readString();     attrTwo = stream.readInt()define the required writeSQL() method   public void writeSQL(SQLOutput stream)    throws SQLException {      stream.writeString(attrOne);    stream.writeInt(attrTwo);  }}String typeName)    throws SQLException  {    sql_type = typeName;    attrOne = stream.readString();    attrTwo = stream.readInt();  }    // define the required writeSQL() method   public void writeSQL(SQLOutput stream)    throws SQLException  {     stream.writeString(attrOne);    stream.writeInt(attrTwo);  }}确保流写入/阅读的输入和顺序以及您oracle类型相同,因为任何不一致都会导致内部错误。5 R4 e  Y' E5 [6 W# x
然后在主类中映射如下:. x# |) F5 K& D
CallableStatement stmt = conn.prepareCall("begin myprocedure(,); end;");stmt.setString(1,"foo");stmt.registerOutParameter(2,java.sql.Types.ARRAY,"OUTPUTONESQLTYPE"); // YOUR ARRAY TYPE (TO MATCH THE API OUTPUT),NOT OBJECTstmt.execute();Array arr = stmt.getArray (2);Map map = conn.getTypeMap();map.put("TABLEONEEXAMPLE",Class.forName("TestArr")); // YOUR OBJECT TYPE,NOT ARRAY.Object[] values = (Object[]) arr.getArray();for (int i=0; i 结果bieng:8 g4 T: E( s& a( R
M:\Documents\Sample Code\1>javac TestArr.javaM:\Documents\Sample Code\1>javac ArrayTest.javaNote: ArrayTest.java uses unchecked or unsafe operations.Note: Recompile with -Xlint:unchecked for details.M:\Documents\Sample Code\SQLComplexArray>java ArrayTestOpening Oracle connection...done.somethingOne: asomethingTwo: 1somethingOne: bsomethingTwo:
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则