Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为Java方法创建PL/SQL包装函数时获取PLS-00258_Java_Oracle_Plsql_Java Stored Procedures_Loadjava - Fatal编程技术网

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

为Java方法创建PL/SQL包装函数时获取PLS-00258,java,oracle,plsql,java-stored-procedures,loadjava,Java,Oracle,Plsql,Java Stored Procedures,Loadjava,我有以下Java方法(我使用loadjava从Oracle 11g的JAR加载到Oracle 11g数据库中) 现在,我想将这个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; T

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

现在,我想将这个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;

它实际上是它不喜欢的受限返回类型<代码>整数是一个受限制的数字,因此导致:

PLS-00258:呼叫规范中不允许的受限数据类型

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

操作:对PL/SQL正式声明使用无约束类型,即数字、二进制整数或PLS整数

您需要
返回编号
,这样它就不会受到限制:

  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中):

即使使用未索引的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对其进行反编译-这可能会更容易…

谢谢Alex,非常有用的响应-您已经做到了以上几点。你说得对,我需要对集合进行索引。然而,我不太明白你所说的“一个对象类型和一个表”是什么意思-你能在此基础上展开一点吗?@JDor-我已经在我的答案中添加了一个我想要的例子。答案太棒了!教科书之类的东西。非常感谢。
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;
/