我正在尝试调用以下PL/SQL过程,该过程将用户定义的记录类型作为IN
参数。
-- User Defined Record
TYPE EMP_REC IS RECORD
(
id employees.employee_id%type,
name employees.last_name%type,
dept_name departments.department_name%type,
job_title jobs.job_title%type,
salary employees.salary%type,
manager_id employees.employee_id%type,
city locations.city%type,
phone employees.phone_number%type
);
下面是用户定义记录的定义:
-- PURPOSE: Prints all employee information from the employee record
-- Example Of: PROCEDURE that takes in a parameter of RECORD type
PROCEDURE print_employee_all_details(empl1 emp_rec , emp_rec_string OUT VARCHAR2)
我正在查看Oracle JDBC文档,该文档指出JDBC不支持复合类型,如RECORDS:
搜索互联网时转到this link
下面是我尝试将用户定义的记录传递给PL/SQL过程的代码:
public String printEmployeeAllDetails() {
Connection conn = null;
CallableStatement callStmt = null;
String empDetails = null;
try {
// Register the Jdbc Driver
// Class.forName(JDBC_DRIVER_ORACLE);
// Create a Database Connection
conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PWD);
// Create a query string
String callProc = "{call HR.EMP_PKG.print_employee_all_details( ? , ?) }";
// Create a Callable Statement
callStmt = conn.prepareCall(callProc);
// Create descriptor for the Oracle Record type "EMP_REC" required
StructDescriptor recDescriptor = StructDescriptor.createDescriptor("EMP_REC", conn);
// Stage values for each field in the Oracle record in an array
Object[] javaEmpRec = new Object[8];
// Populate those values in the Array
javaEmpRec[0] = 100;
javaEmpRec[1] = "Joe Matthew";
javaEmpRec[2] = "IT";
javaEmpRec[3] = "Senior Consultant";
javaEmpRec[4] = 20000;
javaEmpRec[5] = 101;
javaEmpRec[6] = "lombard";
javaEmpRec[7] = "222333444";
// Cast the java array into the oracle record type
STRUCT oracleEmpRec = new STRUCT(recDescriptor, conn, javaEmpRec);
// Bind Values to the IN parameter
callStmt.setObject(1, oracleEmpRec);
// Register OUT parameter
callStmt.registerOutParameter(2, java.sql.Types.VARCHAR);
// Execute the Callable Statement
callStmt.execute();
// Retrieve the value from the OUT parameter
empDetails = callStmt.getString(2);
System.out.println("Emp Details: " + empDetails);
} catch (SQLException se) {
System.out.println("Exception occured in the database");
System.out.println("Exception message: " + se.getMessage());
System.out.println("Database error code: " + se.getErrorCode());
se.printStackTrace();
} finally {
// Clean up
if (callStmt != null) {
try {
callStmt.close();
} catch (SQLException se2) {
se2.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException se2) {
se2.printStackTrace();
}
}
}
return empDetails;
}
在运行这段代码时,我得到了以下异常:
Exception occured in the database
Exception message: invalid name pattern: HR.EMP_REC
java.sql.SQLException: invalid name pattern: HR.EMP_REC
at oracle.jdbc.oracore.OracleTypeADT.initMetadata(OracleTypeADT.java:554)
at oracle.jdbc.oracore.OracleTypeADT.init(OracleTypeADT.java:471)
at oracle.sql.StructDescriptor.initPickler(StructDescriptor.java:324)
at oracle.sql.StructDescriptor.<init>(StructDescriptor.java:254)
at oracle.sql.StructDescriptor.createDescriptor(StructDescriptor.java:135)
at oracle.sql.StructDescriptor.createDescriptor(StructDescriptor.java:103)
Database error code: 17074
at oracle.sql.StructDescriptor.createDescriptor(StructDescriptor.java:72)
at com.rolta.HrManager.printEmployeeAllDetails(HrManager.java:1214)
at com.rolta.HrManager.main(HrManager.java:1334)
我正在使用ojdbc6.jar
,这是JDBC Thin for All Platforms
标题下的第一个jar,用于Oracle Database 11g Release 2 (11.2.0.4) JDBC Drivers
on this page。
我想知道是否允许将用户定义的记录(作为IN参数)传递到PL/SQL过程?有人尝试过以上操作吗?
4条答案
按热度按时间5w9g7ksd1#
是的,允许使用JDBC将用户定义的数据类型作为IN参数传递。但是它不能是
RECORD
。它必须是一个模式级对象,例如。在PL/SQL中,您可以将记录的引用更改为新的对象类型,或者,如果无法更改其余代码,则可以编写一个快速的小转换器函数,将对象类型转换为记录类型。
rks48beu2#
如果您可以执行匿名PL/SQL块(据我所知,这是可能的),您可以执行以下操作:
在这种情况下,您不需要创建新的数据库对象或更改现有的数据库对象,只需要传递参数值来填充记录。
7uzetpgm3#
我想补充一下Dmitry's answer,它建议您可以通过JDBC使用匿名PL/SQL块,并手动显式地组合
RECORD
类型。如果您正在为单个存储过程寻找解决方案,那么手动编写该块就可以了。但是如果您正在寻找一个 * 通用解决方案 *,为 * 所有 * 具有IN
、OUT
、或IN OUT
RECORD
参数,您可能应该编写一个代码生成器,根据以下查询生成存根这将为您提供
MY_SCHEMA
模式中包含的所有包中的所有RECORD
类型的正式定义,从中您可以生成类似于Dmitry答案中的存根:See more details about this technique in this blog post (from which the query was taken).
vfh0ocws4#
无法传递记录,因为必须是SQL对象才能引用,而不是纯
PL/SQL
对象。创建一个对象就像,
这也是一个痛苦。你不能在这里使用
TYPE
属性。因为TYPE不能有这样的依赖关系。而是指定确切的数据类型。