2

I've got the following Java method (which I've loaded into an Oracle 11g database from its JAR using loadjava)

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

Now, I want to wrap this Java method in a PL/SQL function, but I'm getting a PLS-00258 error with the following code. I presume this is because of the array input parameters? Any suggestions?

  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;
4

1 回答 1

4

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

PLS-00258:CALL 规范中不允许使用受约束的数据类型

原因: C 或 Java 的调用规范不能限制 PL/SQL 形式参数类型。具有约束的 PL/SQL 类型是 NATURAL、NATURALN、POSITIVE、POSITIVEN、SIGNTYPE、INTEGER、INT、SMALLINT、DECIMAL、NUMERIC、DEC 这包括来自 POSITIVEN、NATURALN 的 NOT NULL 约束

行动:对 PL/SQL 正式声明使用不受约束的类型,即 NUMBER、BINARY_INTEGER 或 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;
/

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

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

于 2016-09-22T16:04:08.463 回答