Java 导入片段:
import oracle.sql.StructDescriptor;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.sql.STRUCT;
PLSQL 代码片段:
one_user_type :
CREATE OR REPLACE TYPE one_user_type ABCD IS OBJECT
(
user_id VARCHAR2(120),
user_name VARCHAR2(120)
)
Java 代码片段:
//连接conn;
Object[] userObject1 = new Object[] {
"101", "peter" };
StructDescriptor userDescriptor = StructDescriptor
.createDescriptor("one_user_type", conn);
// The below line takes 2.5 seconds approx to execute.
STRUCT user1 = new STRUCT(userDescriptor, conn, userObject1);
注释:ojdbc6.jar; jdk1.6、Oracle 11g
问题 - 知道为什么这会花费太多时间,以及如何减少它吗?
编辑 1 以回应@Lalit Kumar B 评论:“太多时间”与实际查询执行有关。创建 STRUCT 是为了将记录表/对象表传递给 PLSQL 过程。实际的查询执行只需要 93 毫秒,当调用两个这样的过程时,UI 等待大约 5 秒,它们都获取对象表和我们需要创建 STRUCT 的地方。 因此 2.5 秒被认为太多了,我喜欢微调它。当我检查其他 Java 对象构造、转换、查询执行等的执行时间时,与这个 STRUCT 创建相比,它们都非常低。 考虑到我真正调用 5 个存储过程(将对象表作为参数)的场景,我进行了 5 个不同的调用来为每个存储过程创建 STRUCT,仅创建 STRUCT 总共需要大约 7 秒。这个想法是调用过程、获取结果、放入包装器并发送回 UI。
编辑 2:[09/20] 为了最大限度地减少时间,创建了一个过程,它采用对象表并充当内部调用 5 个过程的包装器。因此,从 Java 代码来看,它只是一个存储过程调用。尽管如此,必须创建一次 STRUCT 以作为输入提供给包装程序。在多次运行时,它观察到 STRUCT 创建可以在 2 秒到 8 秒之间的任何时间进行!!我在创建 STRUCT 的方式上做错了吗?我从下面提供的链接检查了 Oracle 文档,但我不知道我是否偏离了。
如果您需要更多详细信息,请告诉我。
更新:创建 STRUCT 对象和描述符 http://docs.oracle.com/cd/B12037_01/java.101/b10979/oraoot.htm
编辑 3:附加到解决方案[09/23] 公认的解决方案非常适合存储单个对象。如果要传递对象表,则适用如下情况:
PLSQL:
TYPE one_user_table_type IS TABLE OF one_user_type; // Table of Objects
Java:
UserType user = new UserType( "101", "Peter" );
ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor(
"ONE_USER_TABLE_TYPE", conn);
UserType[] userArray = { user };
Array users = new ARRAY(arrayDescriptor, conn, userArray );
callableStatement.setArray(1, users);
最佳答案
我遇到了同样的情况:STRUCT 构造函数真的很慢,因为 Oracle 查询数据库的属性和完整的依赖链,这不仅是一个单独的数据库调用,这会减慢你的速度,而且还会查询一些系统词典。 这在 JavaDoc 中有些暗示。对于 STRUCT-Constructor,因为约束和有效性是在构造时测试的,这只能通过对整个对象定义的数据库查询来实现。
解决方案是使用自定义 java 类并将值直接流式传输到过程调用中,这将完全消除构造函数时间!
它看起来像这样:
public final class MyUserType implements SQLData
{
public String userId;
public String userName;
public MyUserType(){}
public MyUserType( final String userId, final String userName )
{
this.userId = userId;
this.userName = userName;
}
@Override
public String getSQLTypeName() throws SQLException
{
return "one_user_type";
}
@Override
public void readSQL( final SQLInput stream, final String typeName ) throws SQLException
{
userId = stream.readString();
userName = stream.readString();
}
@Override
public void writeSQL( final SQLOutput stream ) throws SQLException
{
stream.writeString( userId );
stream.writeString( userName );
}
}
然后你只需使用:
MyUserType param = new MyUserType( "010", "Peter" );
statement.setInputParameter( 1, param );
关于java - Oracle sql STRUCT 创建花费太多时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25916460/