2012-09-12 120 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')并在其中循环。 –