Java JDBC使用Oracle记录、表和对象类型
如何在Jdbc中检索Oracle集合类型。我找了很多,但没有找到任何答案。以下是我的存储过程工作正常:Java JDBC使用Oracle记录、表和对象类型,java,oracle,jdbc,callable-statement,oracle-objects,Java,Oracle,Jdbc,Callable Statement,Oracle Objects,如何在Jdbc中检索Oracle集合类型。我找了很多,但没有找到任何答案。以下是我的存储过程工作正常: create or replace PACKAGE SHOW_SUP AS TYPE SUP_COF_REC IS RECORD ( SUPPLIER_NAME VARCHAR2(32), COFFEE_NAME VARCHAR(32) ); TYPE_RECORD SUP_COF_REC; TYPE SUP_COF_TAB IS TABLE OF TYPE_RECOR
create or replace PACKAGE SHOW_SUP AS
TYPE SUP_COF_REC IS RECORD (
SUPPLIER_NAME VARCHAR2(32),
COFFEE_NAME VARCHAR(32)
);
TYPE_RECORD SUP_COF_REC;
TYPE SUP_COF_TAB IS TABLE OF TYPE_RECORD%TYPE;
PROCEDURE SHOW_SUPPLIERS (SUP_COF_DET OUT SUP_COF_TAB);
END SHOW_SUP;
create or replace PACKAGE BODY SHOW_SUP AS
PROCEDURE SHOW_SUPPLIERS (SUP_COF_DET OUT SUP_COF_TAB) AS
STR VARCHAR2(2000);
BEGIN
STR:='SELECT SUP_NAME, COF_NAME FROM SUPPLIERS S, COFFEES C WHERE
S.SUP_ID=C.SUP_ID ORDER BY SUP_NAME';
EXECUTE IMMEDIATE(STR) BULK COLLECT INTO SUP_COF_DET;
END SHOW_SUPPLIERS;
END SHOW_SUP;
下面是运行存储过程的Java代码:
String sql="{call SHOW_SUP.SHOW_SUPPLIERS(?)}";
CallableStatement cs = con.prepareCall(sql);
cs.registerOutParameter(1, java.sql.Types.ARRAY, "SUP_COF_TAB"); //LINE 3
//cs.registerOutParameter(1, java.sql.Types.ARRAY, "SHOW_SUP.SUP_COF_TAB"); //LINE 4
cs.execute();
我在第3/4行收到的错误:
SQLException : invalid name pattern: SCOTT.SUP_COF_TAB
java.sql.SQLException: invalid name pattern: SCOTT.SUP_COF_TAB
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:199)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:263)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:271)
at oracle.jdbc.oracore.OracleTypeADT.initMetadata(OracleTypeADT.java:543)
at oracle.jdbc.oracore.OracleTypeADT.init(OracleTypeADT.java:462)
at oracle.sql.ArrayDescriptor.initPickler(ArrayDescriptor.java:1678)
at oracle.sql.ArrayDescriptor.<init>(ArrayDescriptor.java:291)
at oracle.sql.ArrayDescriptor.createDescriptor(ArrayDescriptor.java:206)
at oracle.sql.ArrayDescriptor.createDescriptor(ArrayDescriptor.java:175)
at oracle.sql.ArrayDescriptor.createDescriptor(ArrayDescriptor.java:158)
at oracle.sql.ArrayDescriptor.createDescriptor(ArrayDescriptor.java:125)
at oracle.jdbc.driver.NamedTypeAccessor.otypeFromName(NamedTypeAccessor.java:84)
at oracle.jdbc.driver.TypeAccessor.initMetadata(TypeAccessor.java:89)
at oracle.jdbc.driver.T4CCallableStatement.allocateAccessor(T4CCallableStatement.java:629)
at oracle.jdbc.driver.OracleCallableStatement.registerOutParameterInternal(OracleCallableStatement.java:166)
at oracle.jdbc.driver.OracleCallableStatement.registerOutParameter(OracleCallableStatement.java:207)
at oracle.jdbc.driver.OracleCallableStatementWrapper.registerOutParameter(OracleCallableStatementWrapper.java:1584)
at com.jdbc.callstatement.CallableStatementSample.main(CallableStatementSample.java:48)
我在某处发现可以使用数组描述符或结构描述符,但如何在registerOutParameter中使用它,没有任何文档/站点解释过。我被困在这里。这是不可能的。您只能在jdbc UDT集合中使用sql级别的对象。但在你的情况下,你可以考虑使用SysSReFixCu饰器。 在java sys_refcursor中,游标由普通结果集表示 概念如下: ORACE:
PROCEDURE SHOW_SUPPLIERS (SUP_COF_DET OUT SYS_REFCURSOR);
..
PROCEDURE SHOW_SUPPLIERS (SUP_COF_DET OUT SYS_REFCURSOR) AS
c_cursor SYS_REFCURSOR
BEGIN
open c_cursor for 'SELECT SUP_NAME, COF_NAME FROM SUPPLIERS S, COFFEES C WHERE
S.SUP_ID=C.SUP_ID ORDER BY SUP_NAME';
SUP_COF_DET := c_cursor
END SHOW_SUPPLIERS;
爪哇:
String sql="{call SHOW_SUP.SHOW_SUPPLIERS(?)}";
CallableStatement cs = con.prepareCall(sql);
cs.registerOutParameter(1, OracleTypes.CURSOR);
cs.executeUpdate();
ResultSet rs = (ResultSet) cs.getObject(1);
使用SQL结构化类型的完全限定名,如下所示: cs.registerOutParameter1,java.sql.Types.ARRAY,SHOW_SUP.SUP_COF_选项卡//第3行 要读取out参数,请在java代码中执行以下操作:
// Get the out parameter as java.sql.Array
java.sql.Array ntab = (java.sql.Array) cStmt.getObject(1);
// Now get the rows from the nested table
Object[] rows = (Object[])ntab.getArray();
// For each row
for (Object row: rows) {
// Get the columns
Object[] cols = ((Struct) row).getAttributes();
String supplierName = cols[0].toString();
String coffeeName = cols[1].toString();
}
您的数据库和jdbc驱动程序版本是什么?获取元数据会给出以下信息:驱动程序名称:Oracle jdbc驱动程序,驱动程序版本:11.1.0.7.0-Production,DB名称:Oracle,DB版本:Oracle database 11g Enterprise Edition 11.2.0.1.0版-发布前已尝试过Production。浏览注释过的Java代码行4。唯一会改变的是异常的前两行。它将打印为{SQLException:invalid name pattern:SHOW_SUP.SUP_COF_TAB java.sql.SQLException:invalid name pattern:SHOW_SUP.SUP_COF_TAB}您的Oracle数据库是否早于12c?这些型号应该在12摄氏度工作。获取元数据时会显示以下内容:驱动程序名称:Oracle JDBC驱动程序,驱动程序版本:11.1.0.7.0-Production,数据库名称:Oracle,数据库版本:Oracle Database 11g Enterprise Edition 11.2.0.1.0-ProductionOk。对于较旧的数据库,您可以按照以下链接中的建议使用setPlsqlIndexTable API:
// Get the out parameter as java.sql.Array
java.sql.Array ntab = (java.sql.Array) cStmt.getObject(1);
// Now get the rows from the nested table
Object[] rows = (Object[])ntab.getArray();
// For each row
for (Object row: rows) {
// Get the columns
Object[] cols = ((Struct) row).getAttributes();
String supplierName = cols[0].toString();
String coffeeName = cols[1].toString();
}