我试图从JDBC调用以下pl/sql过程。
create or replace PACKAGE test AS
type testrec_r is record (
val1 number,
val2 varchar2(100)
);
type testarr_t is table of testrec_r index by binary_integer;
function test_func(i_data in testarr_t, o_sum out number, o_totallength out number) return number;
END test;
这就是我试图调用它的方式,但没有成功:
StructDescriptor recDescriptor = StructDescriptor.createDescriptor("test.testrec_r", conn);
STRUCT[] RECORDS_ARRAY = new STRUCT[2];
for (int i = 0; i < 2; i++) {
STRUCT oracle_record = new STRUCT(recDescriptor, conn, new
Object[] {i, "test"});
RECORDS_ARRAY[i] = oracle_record;
}
CallableStatement stmt = conn.prepareCall("{ call TEST.TEST_FUNC(?, ?, ?) }");
ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor("TEST.TESTARR_T", conn);
ARRAY oracle_array = new ARRAY(arrayDescriptor, conn, RECORDS_ARRAY);
// Bind the input record
stmt.setArray(1, oracle_array);
stmt.registerOutParameter(2, Types.NUMERIC);
stmt.registerOutParameter(3, Types.NUMERIC);
stmt.executeUpdate();
double out1 = stmt.getDouble(2);
double out2 = stmt.getDouble(3);
return new Object[] { out1, out2 };
我刚刚读到oracle jdbc不支持pl/sql结构类型。因此,这在“无效名称模式:test.testrec_r”中失败
如何从Java调用这个过程?理想情况下,只使用java库/API,但这似乎几乎是不可能的,在简单的sql调用中封装pl/sql包并调用它的最佳解决方案是什么?
另外,我正在使用Spring JDBCTemplate进行数据库连接。
您不能使用PL/SQL类型,因为它们仅为PL/SQL所知(因为12c更严格地说,这不是事实——请参阅UPD)。此外,包中创建的任何类型都不能被java直接看到
应该在架构级别创建SQL类型。SQL类型对所有人都可见,所有人都可以使用。
create or replace and compile java source named "ArrayOfRecTest" as
import java.io.*;
import java.sql.*;
import oracle.sql.*;
import oracle.jdbc.driver.*;
public class ArrayOfRecTest
{
public static void passArrayOfRec() throws SQLException
{
Connection conn = new OracleDriver().defaultConnection();
StructDescriptor sd = StructDescriptor.createDescriptor("MYREC_TYPE", conn);
ArrayDescriptor ad = ArrayDescriptor.createDescriptor("MYRECARR_TYPE", conn);
STRUCT[] recarr = new STRUCT[2];
for (int i = 0; i < 2; i++) { recarr[i] = new STRUCT(sd, conn, new Object[] {i+1, "value " + (i+1)}); }
ARRAY oracle_array = new ARRAY(ad, conn, recarr);
CallableStatement stmt = conn.prepareCall("{ ? = call testpkg.showArrOfRec(?, ?, ?) }");
stmt.registerOutParameter(1, Types.INTEGER);
stmt.setObject(2, oracle_array);
stmt.registerOutParameter(3, Types.INTEGER);
stmt.registerOutParameter(4, Types.INTEGER);
stmt.execute();
int sizeofArr = stmt.getInt(1);
int total = stmt.getInt(3);
int totalLength = stmt.getInt(4);
System.out.println("passArrayOfRec(total,len)=(" + total + "," + totalLength + ") " + sizeofArr + " records were shown");
}
}
/
create or replace force type myrec_type as object( id number, value varchar2(100));
/
create or replace type myrecarr_type as table of myrec_type;
/
create or replace package testpkg as
procedure passArrayOfRec as language java name 'ArrayOfRecTest.passArrayOfRec()' ;
function showArrOfRec(ra myrecarr_type, total out number, totallength out number) return number;
end testpkg;
/
create or replace package body testpkg as
--OP stuff
type testrec_r is record (val1 number, val2 varchar2(100));
type testarr_t is table of testrec_r index by binary_integer;
function test_func(data in testarr_t, total out number, totallength out number) return number is
begin
<<for_each>> for i in data.first..data.last loop
dbms_output.put_line('data(' || i || ')[val1,val2]=[' || data(i).val1 || ',' || data(i).val2 || ']');
total := nvl(total,0) + data(i).val1;
totallength := nvl(totallength,0) + length(data(i).val2);
end loop for_each;
return data.count;
end test_func;
--end OP stuff
function showArrOfRec(ra myrecarr_type, total out number, totallength out number) return number is
data testarr_t;
begin
for i in ra.first..ra.last loop data(i).val1 := ra(i).id; data(i).val2 := ra(i).value; end loop;
return test_func(data, total, totalLength);
end showArrOfRec;
end testpkg;
/
exec testpkg.passArrayOfRec;
输出:
数据(1)[val1,val2]=[1,值1]
数据(2)[val1,val2]=[2,值2]
显示passArrayOfRec(总计,len)=(3,14)2条记录
12cR1中新增的UPD:使用PL/SQL类型
问题内容: 我试图了解如何调用以as为参数的PL / SQL过程。 考虑以下PL / SQL过程: 在将值绑定到IN参数时,我应该使用哪种方法? 对我来说,一个具有单独的游标记录字段的Java类,因为它是该类的成员和实例数组,它似乎是表示plsql CURSOR的正确方法。当我这样做时,我得到一个SQLException: 我使用了以下设置方法 这是我使用上面的语句得到的例外: 问题答案: 对我来
主要内容:基于表的记录,基于游标的记录,用户定义的记录,将记录作为子程序参数在本章中,我们将讨论和学习PL/SQL中的记录。 记录是可以容纳不同种类的数据项的数据结构。 记录由不同的字段组成,类似于数据库表的一行。 例如,想要在图书馆中跟踪记录图书信息。可能希望跟踪每本书的以下属性,例如标题,作者,主题,图书ID。 包含每个这些项目的字段的记录允许将图书视为逻辑单元,并允许以更好的方式组织和表示其信息。 PL/SQL可以处理以下类型的记录 - 基于表的记录 基于游标的记录
我想用java调用一个记录类型表的存储过程。记录只包含数字,但我必须传递整数和小数。 我还没有为我的问题找到合适的解决方案(无论是OracleCallableStatement还是StoredProcedurey)。
我需要对一个参数为PL/SQL表的过程进行JDBC调用。我正在尝试结构对象。但是我没有做正确的事情。我得到错误: ORA-04043:对象“斯科特”。“对象列表结构”不存在。 以下是代码片段: 参数“?”对于本程序,类型为: 我们非常感谢任何能让我们成功的见解谢谢
我想从Java代码调用SQL服务器2008中的一个存储过程。存储过程以用户定义的表类型为参数(基本上是数组)。请给我Java语法来调用存储过程并将数组作为输入参数传递
问题内容: 如何指定参数为表名? 问题答案: 你不能 相反,您需要将其作为VARCHAR2字符串传递,然后使用动态SQL: 阅读有关Dynamic SQL的信息, 并注意如果不正确地使用它会带来的问题,例如性能,可伸缩性和安全性较差。