java - 为 Java 方法创建 PL/SQL 包装函数时获取 PLS-00258

标签 java oracle plsql java-stored-procedures loadjava

我有以下 Java 方法(我已使用 loadjava 将其从 JAR 加载到 Oracle 11g 数据库中)

public int GatewayClientPoolHA( String[] DAUTAddresses,
            int[] DAUTPortArray,
            String sslKeystorePath,
            String sslKeystorePass )

现在,我想将此 Java 方法包装在 PL/SQL 函数中,但使用以下代码时出现 PLS-00258 错误。我认为这是因为数组输入参数?有什么建议吗?

  CREATE OR REPLACE PACKAGE daut_2fa IS

  TYPE daut_addresses_type IS TABLE OF VARCHAR2(50) INDEX BY BINARY_INTEGER; 
  TYPE daut_port_type IS TABLE OF INTEGER INDEX BY BINARY_INTEGER; 

  FUNCTION GatewayClientPoolHA (
      DAUTAddresses         IN daut_addresses_type,
      DAUTPortArray         IN daut_port_type,
      sslKeystorePath       IN VARCHAR2,
      sslKeystorePass       IN VARCHAR2
 ) RETURN INTEGER;


END daut_2fa;
/
SHOW ERROR


CREATE OR REPLACE PACKAGE BODY daut_2fa IS

  FUNCTION GatewayClientPoolHA (
      DAUTAddresses         IN daut_addresses_type,
      DAUTPortArray         IN daut_port_type,
      sslKeystorePath       IN VARCHAR2,
      sslKeystorePass       IN VARCHAR2
 ) RETURN INTEGER IS LANGUAGE JAVA
   NAME 'daut.GatewayClientPoolHA(java.lang.String[], int[], java.lang.String, java.lang.String) return int';



END daut_2fa;

最佳答案

这实际上是它不喜欢的受限返回类型; INTEGER 是一个受约束的数字,因此导致 the PLS-00258 error :

PLS-00258: constrained datatypes disallowed in CALL Specifications

Cause: A call specification for C or Java cannot have constraints on the PL/SQL formal parameter types. PL/SQL types which have have constraints are NATURAL, NATURALN, POSITIVE, POSITIVEN, SIGNTYPE, INTEGER, INT, SMALLINT, DECIMAL, NUMERIC, DEC This includes NOT NULL constraints from POSITIVEN, NATURALN

Action: Use the unconstrained type for that PL/SQL formal declaration i.e NUMBER, BINARY_INTEGER or PLS_INTEGER

您需要改为RETURN NUMBER,这样它就不受限制:

  FUNCTION GatewayClientPoolHA (
      DAUTAddresses         IN daut_addresses_type,
      DAUTPortArray         IN daut_port_type,
      sslKeystorePath       IN VARCHAR2,
      sslKeystorePass       IN VARCHAR2
 ) RETURN NUMBER IS LANGUAGE JAVA
   NAME daut.GatewayClientPoolHA(java.lang.String[], int[], java.lang.String, java.lang.String) return int';

...但随后你会遇到(无论如何在 11gR2 中):

PLS-00999: implementation restriction (may be temporary) INDEX TABLE parameters are disallowed

即使使用未索引的 PL/SQL 表,您仍然会得到:

PLS-00999: implementation restriction (may be temporary) Non-schema collection parameters are disallowed in Java callout

因此,您需要架构级别(不是 PL/SQL)集合,在创建包之前将其创建为单独的类型:

CREATE TYPE daut_addresses_type IS TABLE OF VARCHAR2(50)
/
CREATE TYPE daut_port_type IS TABLE OF NUMBER
/

CREATE OR REPLACE PACKAGE daut_2fa IS

  FUNCTION GatewayClientPoolHA (
      DAUTAddresses         IN daut_addresses_type,
      DAUTPortArray         IN daut_port_type,
      sslKeystorePath       IN VARCHAR2,
      sslKeystorePass       IN VARCHAR2
 ) RETURN NUMBER;


END daut_2fa;
/

CREATE OR REPLACE PACKAGE BODY daut_2fa IS

  FUNCTION GatewayClientPoolHA (
      DAUTAddresses         IN daut_addresses_type,
      DAUTPortArray         IN daut_port_type,
      sslKeystorePath       IN VARCHAR2,
      sslKeystorePass       IN VARCHAR2
 ) RETURN NUMBER IS LANGUAGE JAVA
   NAME 'daut.GatewayClientPoolHA(java.lang.String[], int[], java.lang.String, java.lang.String) return int';

END daut_2fa;
/

Package body DAUT_2FA compiled

SHOW ERRORS

No errors.

不过,未索引的集合可能对您来说是一个问题,因为您可能将相关值放在两个列表中的相同索引位置中。如果您可以将其解压为 Java 中的结构,那么您可能需要一个对象类型和一个包含这些类型的表。像这样的东西:

import oracle.sql.STRUCT;
public class daut {
  public int GatewayClientPoolHA( STRUCT[] DAUTAddressesAndPorts,
              String sslKeystorePath,
              String sslKeystorePass )
  {
    ...
  }
}

然后

CREATE TYPE daut_addresses_port_type AS OBJECT (
  address VARCHAR2(50),
  port number
)
/

CREATE TYPE daut_addresses_port_tab_type AS TABLE OF daut_addresses_port_type
/

CREATE OR REPLACE PACKAGE daut_2fa IS

  FUNCTION GatewayClientPoolHA (
      DAUTAddressesAndPorts IN daut_addresses_port_tab_type,
      sslKeystorePath       IN VARCHAR2,
      sslKeystorePass       IN VARCHAR2
 ) RETURN NUMBER;

END daut_2fa;
/

CREATE OR REPLACE PACKAGE BODY daut_2fa IS

  FUNCTION GatewayClientPoolHA (
      DAUTAddressesAndPorts IN daut_addresses_port_tab_type,
      sslKeystorePath       IN VARCHAR2,
      sslKeystorePass       IN VARCHAR2
 ) RETURN NUMBER IS LANGUAGE JAVA
   NAME 'daut.GatewayClientPoolHA(oracle.sql.STRUCT[], java.lang.String, java.lang.String) return int';

END daut_2fa;
/

an example in the documentation传递对象类型;这只是更进一步并传递对象集合,因此您应该能够引用数组的每个 STRUCT 元素,对对象/结构的每个字段使用适当的类型映射。虽然我还没有真正尝试过那部分。

或者使用单个字符串varray,但连接端口值(例如'127.0.0.1:1521')并在Java中对其进行分解 - 这可能会更容易。 ..

关于java - 为 Java 方法创建 PL/SQL 包装函数时获取 PLS-00258,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39643287/

相关文章:

java - 简单的纸牌游戏,让用户选择游戏中的牌组数量

oracle - 列不可为空延迟

java - Android - 比较 Array/Arraylist 元素以预先检查复选框的有效方法

java - 将产品存储在 TreeSet 中并将内容打印在 JTable 中

Oracle SQL Developer 无法启动

sql - Oracle:如何在比较操作中从子查询中引用带有空格的别名

linux - 无法使用外部表读取文件或使用 PL/SQL 使用 UTL_FILE 写入文件

plsql - Oracle10gv2中使用sys_refcursor发送嵌套表

sql - Oracle SQL : Use sequence in insert with Select Statement

java - DAO方法都返回NullPointerException