2013-03-19 15 views
6

Çalıştırmak, belge ve forumlarda arama yapmak ve takılmamak için aşağıdaki kodla uğraşıyorum. Son olarak, senden yardım istemeye karar verdim. Elimde bulunanlar TYPES, FUNCTION bildirimleri ve FUNCTION VÜCUT beyanı ile pakettir. Gelecekte SYNONYM'i MYPACKAGE için kullanmak istiyorum (Bu sadece sahte değil - Veritabanımda paket ve tip bildirimi olmayacak, ancak prosedürleri/işlevleri çalıştırmak için harici veritabanına ve Java koduna dblink kullanıyorum ama şimdi erişilebilir bu dbLink) ve mypackage dblink üzerinden erişilebilir bir şey olacak:İlkbaharda SimpleJdbcCall ile Mücadele Oracle işlevini çağırmak için

create public synonym dblink_MYPACKAGE for [email protected]_externalDB; 

ve Java Code dblink_MYPACKAGE yerine mypackage kullanacak. (ancak bu önemli değil değil mi?) Dış veritabanı bizim değil, bu yüzden, herhangi bir değişiklik CAN NOT ...

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 ; 

HATA geçerli: org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; SQL için sınıflandırılmamış SQLException [{? = MYPACKAGE.MYFUNCTION (?,?)}] öğesini arayın; SQL durumu [99999]; hata kodu [17074]; geçersiz ad kalıbı: MYPACKAGE.CUSTOMELEMENTSTYPE; iç içe istisna java.sql.SQLException: geçersiz ad kalıbı: MYPACKAGE.CUSTOMELEMENTSTYPE

Sorun yalnızca OUT parametresiyle, OUT (OUT) parametresini geçmediğimde ve MYFUNCTION başka bir sürümüyle çalıştırıldığında aynı kod çalışır; OUT parametresi değil.

Ben OracleTypes.ARRAY (geçersiz adı deseni) ve OracleTypes.OTHER ile de çalıştı (: java.sql.SQLException: Neden Olduğu Yanlış sütun türü: 1111)

+1

Bu sorunu çözüyor musunuz? Ben bu gibi bir şeyle karşılaşıyorum – Forhad

+0

Hatırladığım kadarıyla, Oracle'da yaptık. Bu jdbc tarafından desteklenen bir tür nod oldu, bu yüzden orijinal işlevi çağıran bir sarılmış işlev/prodecure yazdık ama yeni bir doğru parametre türleri vardı. Orjinali sunucumuz olmadığı için dblink ile erişildi, orada herhangi bir şey değiştiremedik. –

cevap

3

hatalı yöntem çağrısı çıktığı görülmektedir: Kodunuz: .withProcedureName ("myFunction") [..] .withFunctionName değiştirilmesi gerektiğini [...] burada

bütün işlev çağrısı bazı basit Examle geçerli:

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 Daha fazla IN veya INOUT parametresi ekleyebilirsiniz, aynı problemler benim için sorunsuz çalışır. –

İlgili konular