# **[JAVA] SimpleJdbcCall呼叫ORACLE內的Package內的Procedure**
###### tags: `Java` `工作筆記`
### ORACLE內的Pakage
假設有個包含所有取餘額的專屬package,裡面有AA/BB/CC/DD/EE五種procedure,(各有不同的取餘額邏輯,且輸入/輸出參數略有不同)
![Uploading file..._uy1dka4al]()
### 作法
這邊示範AA/BB/CC的呼叫方法 (因為他們的輸入/輸出參數相同,固封裝成一個方法)
這邊有一點需要注意,在`.declareParameters()`宣告參數時,Oracle其實不會看Key的名稱抓value,而是依照順序丟入。所以宣告的順序必須和procedure內一模一樣,不然回傳的MAP結果會錯亂。
```java=
public ProcedureGetBalDTO execGetAaBbCcBal(String precedureName, String accidno, String queryDate) {
SimpleJdbcCall simpleJdbcCallRefCursor = new SimpleJdbcCall(jdbcTemplate)
.withCatalogName("QUERY_BAL_PKG") //package名
.withProcedureName(precedureName) //procedure名,這邊範例使用參數傳入(AA/BB/CC其中一個)
.withoutProcedureColumnMetaDataAccess()
.declareParameters(
new SqlParameter("P_accidno", Types.NVARCHAR), // 設定對應於Prodedure內IN、OUT參數
new SqlParameter("P_inq_date", Types.NVARCHAR),
new SqlOutParameter("P_last_date", Types.NVARCHAR),
new SqlOutParameter("P_last_bal", Types.NVARCHAR),
new SqlOutParameter("P_Retcode", Types.NVARCHAR)
);
simpleJdbcCallRefCursor.setAccessCallParameterMetaData(false);
Map<String, Object> params = new HashMap<>();
params.put("P_accidno", accidno);
params.put("P_inq_date", queryDate);
params.put("P_last_date", "");
params.put("P_last_bal", "");
params.put("P_Retcode", "");
Map<String, Object> map = simpleJdbcCallRefCursor.execute(params);
ProcedureGetBalDTO result = new ProcedureGetBalDTO();
result.setLastDate((String)map.get("P_last_date"));
result.setLastBal((String)map.get("P_last_bal"));
result.setRetcode((String)map.get("P_Retcode"));
log.atInfo().log("exec get TWD (AA/BB/CC) bal finish , result => retCode: %s, lastDate:%s , lastBal:%s", result.getRetcode(),result.getLastDate(),result.getLastBal());
return result;
}
```