我收到java.sql.SQLException:当尝试访问存储过程(在oracle中创建)时,在索引:: 2时缺少IN或OUT参数,该存储过程具有客户端名称(varchar)作为输入参数& cursor作为输出参数。当我通过JSP页面测试它时会出现错误,但是当我通过Junit测试stroed proc时,我没有收到错误。所以我很困惑。请在下面找到我存储的proc&还有正在通话的DAOImpl类。我可以看到JSP页面正确地将名称从输入文本框传递到存储过程的名称输入参数。
PROCEDURE sp_get_client_details_by_name (
p_client_name IN ncr.ncr_parties.full_legal_name%TYPE,
p_result_set OUT SYS_REFCURSOR)
AS
BEGIN
OPEN p_result_set FOR
SELECT np.newedge_party_id AS client_id,
np.full_legal_name AS client_name,
np.city,
nc.name residence_country_name,
np.life_cycle_status AS status,
ec_addr.addr2 AS client_address1,
ec_addr.title_dist_compl AS client_address2,
ec_addr.zip AS client_address3,
ec_addr.state AS client_address4,
ec_addr.title_compl AS client_address_tc,
ec_addr.locality_compl AS client_address_lc,
le.newedge_legal_entity_id AS legal_entity_id,
le.full_legal_name AS legal_entity_name,
le_addr.addr2 AS legal_entity_address1,
le_addr.title_dist_compl AS legal_entity_address2,
le_addr.zip AS legal_entity_address3,
le_addr.state AS legal_entity_address4,
le_addr.title_compl AS legal_entity_address_tc,
le_addr.locality_compl AS legal_entity_address_lc
FROM ncr.ncr_parties np
JOIN ncr_legal_entities le
ON np.legal_entity_key = le.legal_entity_key
JOIN ncrglobalcountryview_vw nc
ON nc.country_alias_key = np.residence_country_aliases_key
JOIN ncr_cpty_addresses ec_addr
ON ec_addr.cpty_key = np.party_key
AND ec_addr.cpty_level = 'P'
AND ec_addr.addr_type_key = 1
JOIN ncr_cpty_addresses le_addr
ON le_addr.cpty_key = le.legal_entity_key
AND le_addr.cpty_level = 'LE'
AND le_addr.addr_type_key = 1
WHERE np.full_legal_name LIKE '%' || p_client_name || '%';
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
SQLERRM || ' backtrace: ' || DBMS_UTILITY.format_error_backtrace);
raise_application_error (
'-20000',
'Unknown exception occurred. Please contact support.' || SQLERRM);
END sp_get_client_details_by_name;
END pkg_ocr_gui;
public class ECIDDetailsDAOImpl implements ECIDDetailsDAO {
private DataSource dataSource;
private static final String SP_GET_ECID_DETAILS = "ncr.pkg_ocr_gui.sp_get_client_details_by_name";
private static final String EC_ID_NAME_PARAM = "p_client_name";
private static final String ECID_CUR_TYPES = "p_result_set";
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public List<ECIDDetails> getECIDDetails(String elementaryClientName) {
GetECIDDetailsStoredProcedure getECIDDetailsStoreProc = new GetECIDDetailsStoredProcedure(dataSource, SP_GET_ECID_DETAILS);
Map<String, Object> resultsMap = getECIDDetailsStoreProc.executeECIDetails(elementaryClientName);
List<ECIDDetails> ecidDetails = (List<ECIDDetails>) resultsMap.get(ECID_CUR_TYPES);
return ecidDetails;
}
class GetECIDDetailsStoredProcedure extends StoredProcedure {
public GetECIDDetailsStoredProcedure(DataSource dataSource, String sprocName) {
super(dataSource, sprocName);
declareParameter(new SqlParameter(EC_ID_NAME_PARAM, java.sql.Types.VARCHAR));
declareParameter(new SqlOutParameter(ECID_CUR_TYPES, OracleTypes.CURSOR, new BeanPropertyRowMapper<ECIDDetails>(ECIDDetails.class)));
compile();
}
public Map<String, Object> executeECIDetails(String elementaryClientName) {
Map <String, Object> inputs = new HashMap<String, Object>();
inputs.put(EC_ID_NAME_PARAM, elementaryClientName);
return super.execute(inputs);
}
}
}
以下是我的JUnit测试,它提供了适当的数据
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:test-applicationcontext.xml"})
public class ECIDFetchServiceTest {
@Autowired
ECIDDetailsDAOImpl ecIDDAO;
@Test
public void validategetECIDDetails() {
List<ECIDDetails> ecidDetails = new ArrayList<ECIDDetails>();
ecidDetails = ecIDDAO.getECIDDetails("ABN");
assertNotNull(ecidDetails);
assertTrue(ecidDetails.size() > 0);
}
}
嗨Priyesh,
我正在使用JSF来创建UI。请在下面找到必要的代码。
JSF代码
<h:panelGrid columns="3" cellspacing="5" cellpadding="5">
<h:outputLabel value="Elementary Client Name" />
<h:inputText value="#{ecIDBean.elementaryClientName}" />
<h:commandButton value="Get EC" action="#{ecIDBean.executeEcIDList}">
</h:commandButton>
</h:panelGrid>
托管Bean类
public class ECIDFetchBean {
private String elementaryClientName;
private List<ECIDDetails> ecIDList;
private ECIDFetchService ecIDFetchService;
public ECIDFetchBean() {
ApplicationContext ctx = ApplicationContextProvider.getApplicationContext();
ecIDFetchService = (ECIDFetchServiceImpl)ctx.getBean("ecIDFetchService");
}
public String getElementaryClientName() {
return elementaryClientName;
}
public void setElementaryClientName(String elementaryClientName) {
this.elementaryClientName = elementaryClientName;
}
public List<ECIDDetails> getEcIDList() {
return ecIDList;
}
public void setEcIDList(List<ECIDDetails> ecIDList) {
this.ecIDList = ecIDList;
}
public void executeEcIDList() {
ecIDList = ecIDFetchService.getECIDDetails(elementaryClientName);
}
}
服务类
public class ECIDFetchServiceImpl implements ECIDFetchService {
private ECIDDetailsDAO ecidDetailsDAO;
public List<ECIDDetails> getECIDDetails(String elementaryClientName) throws OCRReportingException {
return ecidDetailsDAO.getECIDDetails(elementaryClientName);
}
嗨Priyesh,
JSP也指向同一个数据库。我改变了我的DAOImpl类来调用存储过程 SimpleJdbcCall&amp;它现在从JUnit和JSP都运行良好。
public List<ECIDDetails> getECIDDetailsBySimpleJDBCCall(String elementaryClientName){
SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(dataSource);
simpleJdbcCall.withCatalogName("ncr.pkg_ocr_gui").withProcedureName("sp_get_client_details_by_name")
.withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlParameter(EC_ID_NAME_PARAM, java.sql.Types.VARCHAR),
new SqlOutParameter(ECID_CUR_TYPES, OracleTypes.CURSOR, new BeanPropertyRowMapper<ECIDDetails>(ECIDDetails.class)));
MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource();
sqlParameterSource.addValue(EC_ID_NAME_PARAM, elementaryClientName);
Map<String, Object> results = simpleJdbcCall.execute(sqlParameterSource);
List<ECIDDetails> ecidDetails = (List<ECIDDetails>) results.get(ECID_CUR_TYPES);
return ecidDetails;
}