2017-08-17 77 views
0

问题描述: 我想通过java代码调用存储在我的数据库中的过程。我想调用的过程有一个类型为'MAP_VARCHAR'的参数(我已经将它定义为下面的包中的类型)。java.sql.SQLException:从jdbc执行程序包级别类型时无效的列类型

现在,我试图从我的java代码执行此过程,但传递参数是给java.sql.SQLException。

SQL包来告诉你怎么创建我的SQL程序,并输入

-------------------------------------------------------- 
-- Package Body TEST_PACKAGET 
-------------------------------------------------------- 

    CREATE OR REPLACE EDITIONABLE PACKAGE BODY "TEST_PACKAGE" AS 

    PROCEDURE PerformersRole(P_Performer_Map MAP_VARCHAR) AS 
    BEGIN 

     DBMS_OUTPUT.PUT_LINE('Hello ' || P_Performer_Map('Engineer')); 

    END PerformersRole; 

END TEST_PACKAGE; 

/
-------------------------------------------------------- 
-- Package TEST_PACKAGE 
-------------------------------------------------------- 

    CREATE OR REPLACE EDITIONABLE PACKAGE "TEST_PACKAGE" AS 

    /* TODO enter package declarations (types, exceptions, methods etc) here */ 
    TYPE MAP_VARCHAR IS TABLE OF VARCHAR(100) INDEX BY VARCHAR(100); 

    PROCEDURE PerformersRole(P_Performer_Map MAP_VARCHAR); 
END TEST_PACKAGE; 

/

我的Java代码

public void executeProcedure(){ 

     CallableStatement statement = null; 
     try { 

/// Oracle Connection code should be here 
      Connection connection = connectionManager.createConnection(); 


      Hashtable newMap = new Hashtable(); 

      newMap.put("Engineer", "Hanson"); 
      newMap.put("Assistant", "Alice Kim"); 
      newMap.put("Supervisor", "James MaCoy"); 


      StringBuffer procedure = new StringBuffer("{call TEST_PACKAGE.PerformersRole(?) }"); 
      statement = connection.prepareCall(procedure.toString()); 
      statement.setInt(1, newMap); 

      statement.execute(); 
     } catch (Exception ex) { 


     } 

} 

当我执行我收到错误我的java代码是

java.sql.SQLException: Invalid column type 
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:8761) 
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8259) 
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9012) 
    at oracle.jdbc.driver.OracleCallableStatement.setObject(OracleCallableStatement.java:4983) 
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:230) 

我缺少什么?!

感谢您的帮助,提前

+0

SQL包类型麻烦你的程序似乎并没有接受一个整数作为输入值,必须有一些比'setInt'更相关的方法。 – Berger

+0

什么是MAP_VARCHAR类型? – user7294900

+0

MAP_VARCHAR是自定义类型,它将保存VARCHAR表并由VARCHAR建立索引。即项目('马德里'):='皇家马德里' – Hanson

回答

0

OK,我已经花时间试图找出我怎么能解决这个问题的Arkadiusz卢卡西维奇评论后,因为他没有提供任何正式文件提的是,我做了快速研究,似乎他的要求是合法的。

有克服从Java访问SQL包级别类型的问题,方法2:

方法#1
通过Panser在以下网址提供
[https://stackoverflow.com/a/25989632/8477836][1]

所有答案你需要的是构建SQL DECLARE ... BEGIN ... END块,然后从你的java中执行它。

方法2
我插入水平型(MAP_VARCHAR)值我想在程序通过在单独的表中,然后我的SQL封装内,我创建函数使用光标从表中检索这些值我创建并返回的值存储到一具有(MAP_VARCHAR)

功能的类型,这将是负责存储MAP_VARCHAR

FUNCTION GET_MAP_VARCHAR(P_PROCESS_ID NUMBER) 
    RETURN MAP_VARCHAR IS 
     LV_MAP_VARCHAR MAP_VARCHAR; 
     LV_MAP_VARCHAR_TABLE_ROW EPAD_WF_RESD_PRFM_RLE%ROWTYPE; 

     CURSOR C_GET_MAP_VARCHAR_ROWIS 
      SELECT * FROM TEST T 
      WHERE T.TEST = P_PROCESS_ID; 

    BEGIN 

     FOR R_GET_MAP_VARCHAR_ROWIN C_GET_MAP_VARCHAR_ROWLOOP 
     LV_MAP_VARCHAR(R_GET_MAP_VARCHAR_ROW .ROLE):= R_GET_MAP_VARCHAR_ROW.NAME; 
     END LOOP; 

    RETURN LV_MAP_VARCHAR; 

    END GET_MAP_VARCHAR 
我的本地变量3210

我的新的SQL程序应该是这样的:

CREATE OR REPLACE EDITIONABLE PACKAGE BODY "TEST_PACKAGE" AS 

    PROCEDURE PerformersRole(P_ID Number) AS 

    LV_Performer_Map MAP_VARCHAR 
    BEGIN 
    LV_Performer_Map MAP_VARCHAR= GET_MAP_VARCHAR(P_PROCESS_ID NUMBER); 

     DBMS_OUTPUT.PUT_LINE('Hello ' || LV_Performer_Map('Engineer')); 

    END PerformersRole; 

希望这将帮助任何人面临着访问从Java

0

在Oracle 11.2不可能使用包级别类型的JDBC。并且不可能在sql级别上创建关联数组。

此代码将失败。

create TYPE MAP_VARCHAR IS TABLE OF VARCHAR(100) INDEX BY VARCHAR(100); 

一个例外是binary_integer的varchar或number索引的关联数组。 Accessing PL/SQL Associative Arrays

+0

感谢您对我有用的评论@ArkadiuszŁukasiewicz我希望我可以投它为有用的,但我刚刚创建了我的账户,我无法投票,因为我的声望<15 – Hanson

相关问题