我有一个大型的Oracle PL / SQL包,其中包含几个带有IN和OUT类型参数的过程。其中一些参数是用户定义的类型。其中一些是在同一个包中定义的类型。 (定义的包装规范)。
有没有一种直接从Oracle Package生成Java代码的简单方法,可以用来通过JDBC调用这些过程?
答案 0 :(得分:1)
首先,直到Oracle 11g,无法通过Oracle的字典视图轻松发现软件包类型,而且它们很难通过JDBC进行序列化/反序列化。如果要在Java中支持存储过程中的包类型,最好是编写桥接方法,以SQL TABLE
/ VARRAY
/ OBJECT
类型包装/解包包类型。更多信息:
为所有包和独立例程(过程/函数)以及可能涉及的所有TABLE
/ VARRAY
/ OBJECT
类型编写源代码生成器,你必须查询以下字典视图:
<强>包强>
SELECT *
FROM ALL_OBJECTS
WHERE OBJECT_TYPE = 'PACKAGE'
独立例程
SELECT *
FROM ALL_OBJECTS
WHERE OBJECT_TYPE IN ('FUNCTION', 'PROCEDURE')
打包例程
(注意重载例程和其他警告)
SELECT *
FROM ALL_OBJECTS o
JOIN ALL_PROCEDURES p ON o.OWNER = p.OWNER AND o.OBJECT_NAME = p.OBJECT_NAME
WHERE o.OBJECT_TYPE = 'PACKAGE'
常规参数
SELECT *
FROM ALL_ARGUMENTS
TABLE
/ VARRAY
类型
SELECT *
FROM ALL_COLL_TYPES
WHERE COLL_TYPE IN ('VARYING ARRAY', 'TABLE')
OBJECT
类型
SELECT *
FROM ALL_TYPES
WHERE TYPECODE = 'OBJECT'
OBJECT
属性
SELECT *
FROM ALL_TYPE_ATTRS
使用上述信息,您可以生成必要的源代码,同时考虑以下功能:
OUT
参数需要使用适当的java.sql.Types
类型注册到CallableStatement
。OBJECT
类型必须在每个绑定变量的特定类型映射中注册OBJECT
类型应生成为java.sql.SQLData
。MEMBER PROCEDURES
类型上使用面向对象的PL / SQL(OBJECT
,最好使用非OO语法将OBJECT
值作为{{{ 1}}参数)。SELF
API创建TABLE
和VARRAY
类型引用。createARRAY()
和OBJECT
/ TABLE
类型时需要特别小心,有很多警告,尤其是当VARRAY
或BLOB
值为参与。CLOB
类型需要考虑在内。您可以使用jOOQ,这是一个商业图书馆,为上述所有内容提供原生支持。 (免责声明:我在jOOQ背后工作)一个典型的例子如下:
REF CURSOR
使用jOOQ,您可以按如下方式调用CREATE TYPE FILM_T AS OBJECT (
film_id int,
title VARCHAR(255)
);
/
CREATE TYPE FILMS_T AS TABLE OF FILM_T;
/
CREATE TYPE CUSTOMER_T AS OBJECT (
customer_id INT,
first_name VARCHAR(45),
last_name VARCHAR(45)
);
/
CREATE TYPE CUSTOMER_RENTAL_HISTORY_T AS OBJECT (
customer CUSTOMER_T,
films FILMS_T
);
/
CREATE PACKAGE RENTALS AS
FUNCTION GET_CUSTOMER_RENTAL_HISTORY(p_customer CUSTOMER_T)
RETURN CUSTOMER_RENTAL_HISTORY_T;
END RENTALS;
/
函数:
RENTALS.GET_CUSTOMER_RENTAL_HISTORY