首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为Oracle PL/SQL包生成JDBC代码

为Oracle PL/SQL包生成JDBC代码
EN

Stack Overflow用户
提问于 2015-04-24 07:41:39
回答 1查看 1.1K关注 0票数 2

我有一个大型的Oracle PL/SQL包,它有几个带有IN和OUT类型参数的过程。其中几个参数是用户定义的类型。其中一些是在同一个包中定义的类型。(定义包装规格)。

是否有一种从Oracle包直接生成Java代码的简单方法,可用于通过JDBC调用这些过程?

EN

Stack Overflow用户

发布于 2015-11-01 11:49:49

首先,直到Oracle 11g,通过Oracle的字典视图无法很容易地发现包类型,而且它们很难在JDBC上序列化/反序列化。如果您希望支持Java存储过程中的包类型,最好是编写桥式方法,将包类型包装/解包到SQL TABLE / VARRAY / OBJECT类型中。更多信息在这里:

自己编写这样的代码生成器:

为了为所有包和独立例程(过程/函数)以及可能涉及的所有TABLE / VARRAY / OBJECT类型编写源代码生成器,您必须查询以下字典视图:

代码语言:javascript
运行
复制
SELECT *
FROM ALL_OBJECTS
WHERE OBJECT_TYPE = 'PACKAGE'

独立例程

代码语言:javascript
运行
复制
SELECT *
FROM ALL_OBJECTS
WHERE OBJECT_TYPE IN ('FUNCTION', 'PROCEDURE')

包例程

(注意过载的例程和其他注意事项)

代码语言:javascript
运行
复制
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'

例程参数

代码语言:javascript
运行
复制
SELECT *
FROM ALL_ARGUMENTS

TABLE / VARRAY type

代码语言:javascript
运行
复制
SELECT *
FROM ALL_COLL_TYPES
WHERE COLL_TYPE IN ('VARYING ARRAY', 'TABLE')

OBJECT 类型

代码语言:javascript
运行
复制
SELECT *
FROM ALL_TYPES
WHERE TYPECODE = 'OBJECT'

OBJECT 属性

代码语言:javascript
运行
复制
SELECT *
FROM ALL_TYPE_ATTRS

使用上述信息,您可以生成必要的源代码,同时考虑到以下特性:

  • OUT参数需要用其适当的java.sql.Types类型注册到CallableStatement
  • OBJECT类型必须在每个绑定变量的特定类型映射中注册。
  • OBJECT类型应该以java.sql.SQLData的形式生成。
  • 如果您使用的是面向对象的PL/SQL (MEMBER PROCEDURES on OBJECT类型,最好使用传递OBJECT值的非OO语法作为SELF参数)。
  • TABLEVARRAY类型引用必须使用ojdbc的createARRAY() API创建。
  • 当嵌套OBJECTTABLE / VARRAY类型时,需要特别小心,有许多警告,特别是当涉及BLOBCLOB值时。
  • 需要考虑REF CURSOR类型。
  • 包中的重载过程最好通过使用PL/SQL命名参数语法来消除歧义。

使用第三方库

您可以使用jOOQ,这是一个商业库,它为上述所有内容提供了本机支持。(免责声明:我在jOOQ背后的公司工作)一个典型的例子是:

代码语言:javascript
运行
复制
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;
/

然后,可以使用jOOQ调用RENTALS.GET_CUSTOMER_RENTAL_HISTORY函数,如下所示:

代码语言:javascript
运行
复制
CustomerRentalHistoryTRecord result =
  Rentals.getCustomerRentalHistory(config, new CustomerTRecord(1, "John", "Wayne"))

for (FilmTRecord film : result.getFilms()) {
  System.out.println(film.getTitle());
}
票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29841540

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档