2012-09-12 51 views
3

我想用Spring jdbc執行Oracle函數。使用Spring執行Oracle函數jdbc

但我得到以下錯誤

CallableStatementCallback; bad SQL grammar [{? = call RATELIMIT_OWN.GET_LOGS(?, ?)}]; nested exception is java.sql.SQLException: ORA-06550: line 1, column 24: PLS-00653: aggregate/table functions are not allowed in PL/SQL scope ORA-06550: line 1, column 13: PLS-00382: expression is of wrong type ORA-06550: line 1, column 7: PL/SQL: Statement ignored 

SQL函數

CREATE OR REPLACE FUNCTION RATELIMIT_OWN.Get_Logs (p_yyyymm VARCHAR2, p_numec NUMBER) 
    RETURN LOG_RECORD_TABLE PIPELINED IS 

TYPE  ref0 IS REF CURSOR; 
cur0  ref0; 

out_rec  LOG_RECORD := log_record(NULL,NULL,NULL); 

BEGIN 

OPEN cur0 FOR 
    'SELECT eventid, errormsg, create_date from logs partition (LOGS_P' || p_yyyymm || ') where numec=:1' 
USING p_numec; 

    LOOP 
    FETCH cur0 INTO out_rec.eventid, out_rec.msg, out_rec.create_date; 
    EXIT WHEN cur0%NOTFOUND; 
    PIPE ROW(out_rec); 
    END LOOP; 
    CLOSE cur0; 

RETURN; 
END Get_Logs; 
/

Java代碼

public int getLogs(RateLimitLogBean inputBean) { 
    SimpleJdbcCall caller = new SimpleJdbcCall(this.jdbcTemplateMartinique).withSchemaName("RATELIMIT_OWN").withFunctionName("Get_Logs").withReturnValue() 
      .declareParameters(new SqlOutParameter("EVENTID", Types.VARCHAR)) 
      .declareParameters(new SqlOutParameter("MSG", Types.VARCHAR)) 
      .declareParameters(new SqlOutParameter("CREATE_DATE", Types.DATE)) 
      .declareParameters(new SqlParameter("P_YYYYMM", Types.VARCHAR)) 
      .declareParameters(new SqlParameter("P_NUMEC", Types.INTEGER)); 
    RateLimitLogBean resultBean = null; 

    SqlParameterSource paramMap = new MapSqlParameterSource().addValue(P_YYYYMM, inputBean.getMonth(), Types.VARCHAR).addValue(P_NUMEC, inputBean.getNumec(), Types.INTEGER); 
    caller.compile(); 

    Object obj = caller.execute(paramMap); 
    resultBean = caller.executeFunction(RateLimitLogBean.class, paramMap); 
    if (resultBean != null) { 
     transferBeanData(resultBean, inputBean); 
     return 0; 
    } 
    return -1; 
} 

任何想法,爲什麼我收到此錯誤?

回答

5

你不能直接從PL/SQL調用一個管道函數:

SQL> CREATE OR REPLACE TYPE typ IS TABLE OF NUMBER; 
    2/

Type created. 

SQL> CREATE OR REPLACE FUNCTION f RETURN typ PIPELINED IS 
    2 BEGIN 
    3  PIPE ROW (1); 
    4  RETURN; 
    5 END; 
    6/

Function created. 

SQL> DECLARE 
    2  l typ; 
    3 BEGIN 
    4  l := f; 
    5 END; 
    6/
    l typ; 
* 
ERROR at line 2: 
ORA-06550: line 1, column 10: 
PLS-00653: aggregate/table functions are not allowed in PL/SQL scope 

您需要SQL調用一個管道函數:

SQL> SELECT * FROM TABLE(f); 

COLUMN_VALUE 
------------ 
      1 

從Java調用這個函數,使用遊標。

+0

您可以讓我知道我的方案的示例或代碼來執行此功能。 – Reddy

+2

使用'Statement'就好像您想用簡單的SELECT查詢表或視圖一樣。然後檢索遊標('ResultSet')並在其中循環。 –