2013-03-19 13 views
6

Mam problem z poniższym kodem, aby działał, przeszukiwał dokumentację i fora i utknął. W końcu postanowiłem poprosić cię o pomoc. Mam pakiet z TYPAMI, deklaracjami FUNCTION i deklaracją FUNCTION BODY. W przyszłości chciałbym użyć SYNONYM do MYPACKAGE (To jest tylko pozorowanie - nie będę miał deklaracji pakietów i typów w mojej bazie danych, ale użyję dblinka do zewnętrznej bazy danych i kodu Java, aby uruchomić procedury/funkcje, ale teraz nie mam mają tę dblink dostępny) i mypackage będzie coś dostępne za pośrednictwem dblink:Strugowanie wiosną SimpleJdbcCall wywołanie funkcji Oracle

create public synonym dblink_MYPACKAGE for [email protected]_externalDB; 

i będę używał dblink_MYPACKAGE zamiast mypackage w kodzie Java. (ale to nie ma znaczenia, prawda?) Zewnętrznej bazy danych nie jest nasze, więc nie możemy zmienić coś tam ...

public class TestClassSpringBased { 

private DataSource dataSource; 

private SimpleJdbcCall jdbcCall; 

@Override 
public void testMe(Integer id) { 

    int iid = 1; 
    SqlParameterSource in = new MapSqlParameterSource().addValue("IN_1", iid); 

    Map<String, Object> out = jdbcCall.execute(in); 

} 

public DataSource getDataSource() { 
    return dataSource; 
} 

public void setDataSource(DataSource dataSource) { 
    this.dataSource = dataSource; 
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 
    jdbcTemplate.setResultsMapCaseInsensitive(true); 

    this.jdbcCall = new SimpleJdbcCall(dataSource) 
      .withCatalogName("MYPACKAGE") 
      .withProcedureName("MYFUNCTION") 
      .withReturnValue() 
      .useInParameterNames("IN_1") 
      .declareParameters(
        new SqlInOutParameter("IN_1", OracleTypes.NUMBER), 
        new SqlInOutParameter("OUT_1", OracleTypes.STRUCT, "MYPACKAGE.CUSTOMELEMENTSTYPE", 
          new SqlReturnType() { 
           public Object getTypeValue(CallableStatement cs, int colIndx, int sqlType, 
             String typeName) throws SQLException { 

            return null; //just let it work, the I will think what to write here 
           } 
          })); 

} 

} 





create or replace 
PACKAGE   MYPACKAGE IS 


    TYPE CUSTOMELEMENTSTYPE_R IS RECORD (
    C1 VARCHAR2(60), 
    C2 VARCHAR2(30) 

); 

    TYPE CUSTOMELEMENTSTYPE IS TABLE OF CUSTOMELEMENTSTYPE_R 
    INDEX BY PLS_INTEGER; 



FUNCTION MYFUNCTION(
    IN_1 IN INTEGER, OUT_1 OUT CUSTOMELEMENTSTYPE) 
RETURN VARCHAR2; 


    END; 



create or replace 
PACKAGE BODY MYPACKAGE IS 

    FUNCTION MYFUNCTION(
    IN_1 IN INTEGER, OUT_1 OUT CUSTOMELEMENTSTYPE) 
    RETURN VARCHAR2 IS 

    BEGIN 

SELECT * BULK COLLECT INTO OUT_1 
    FROM SOME_TABLE; 
    RETURN 'return param'; 
END MYFUNCTION; 

    END MYPACKAGE ; 

błąd jest: org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; nieskategoryzowany wyjątek SQLException dla SQL [{? = wywołaj MYPACKAGE.MYFUNCTION (?,?)}]; Stan SQL [99999]; kod błędu [17074]; nieprawidłowy wzorzec nazwy: MYPACKAGE.CUSTOMELEMENTSTYPE; Zagnieżdżony wyjątek to java.sql.SQLException: nieprawidłowy wzorzec nazwy: MYPACKAGE.CUSTOMELEMENTSTYPE

Problem dotyczy tylko parametru OUT, działa ten sam kod, gdy nie przekazuję parametru OUT i nie wykonuję go względem innej wersji funkcji MYFUNCTION, która ma parametr OUT.

Próbowałem też z OracleTypes.ARRAY (nieprawidłowa nazwa wzorca) i OracleTypes.OTHER (spowodowane przez: java.sql.SQLException: niewłaściwy typ kolumna: 1111)

+1

Czy rozwiązujesz ten problem? Mam do czynienia z czymś takim – Forhad

+0

O ile pamiętam, zrobiliśmy to na Oracle. Był to typ suportu wspierany przez jdbc, więc napisaliśmy funkcję wraped/prodecure na Oracle nazywającą oryginalną funkcję, ale nowa miała poprawne typy parametrów. Pierwotny był dostępny przez dblink, ponieważ nie był naszym serwerem, nie mogliśmy niczego tam zmienić. –

Odpowiedz

3

Wydaje się, że używasz nieprawidłowej wywołanie metody: Twój kod: .withProcedureName ("myFunction") [..] należy zastąpić .withFunctionName [...]

tu jest jakiś prosty examle całej wywołania funkcji:

JdbcTemplate jdbc = new JdbcTemplate(txManager.getDataSource()); 
    SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbc) 
      .withCatalogName("p_adm_www") 
      .withFunctionName("fn_usr_get_login_sequence") 
      .declareParameters(new SqlOutParameter("RETURN", OracleTypes.NUMBER)) 
      .withoutProcedureColumnMetaDataAccess(); 
    jdbcCall.setAccessCallParameterMetaData(false); 
    BigDecimal returnId = jdbcCall.executeFunction(BigDecimal.class, null); 
    return returnId.longValue(); 
+0

offcourse Możesz dodać więcej parametrów IN lub INOUT, to samo działa dla mnie bez żadnych problemów. –