/** * Overrides the parent method to set replaceable parameters, if any, into the CallableStatement * object. CallableStatements may have to register OUT parameters, as well as set IN and INOUT * parameters. * * @param cs the Statement object. * @param params the array of Param objects. * @return a Statement object which should be cast to CallableStatement. * @exception Exception if there was a problem setting the parameters. */ protected final Statement setParameters(final Statement cs, final Param[] params) throws Exception { CallableStatement tcs = (CallableStatement) cs; for (int i = 0; i < params.length; i++) { // :NOTE: order is important here. For INOUT which will enter // both blocks, we need to set the value and then register the // parameter if (params[i].isInParameter()) { if (params[i].isNull()) { tcs.setNull(i + 1, params[i].getSQLType()); } else { Object convertedParamValue = TypeUtils.convertToObject(params[i].getValue(), params[i].getType()); tcs.setObject(i + 1, convertedParamValue, params[i].getSQLType()); } } if (params[i].isOutParameter()) { if (SymbolTable.isVariableName(params[i].getValue())) { SymbolTable.setValue( SymbolTable.OUT_PARAM + tcs.hashCode() + ":" + i + "}", params[i].getValue()); } String className = TypeMapper.findClassByName(params[i].getType()); if (BigDecimalType.class.getName().equals(className)) { int scale = params[i].getScale(); tcs.registerOutParameter(i + 1, params[i].getSQLType(), scale); } else if (params[i].getTypeName() != null) { tcs.registerOutParameter(i + 1, params[i].getSQLType(), params[i].getTypeName()); } else { tcs.registerOutParameter(i + 1, params[i].getSQLType()); } } } return tcs; }
/** * Overrides the parent method to set the OUT parameters into the DatabaseResult object. * * @param cs the Statement object. * @param params the array of Param objects. * @param result the DatabaseResult object. * @exception Exception if there was a problem setting the OUT params. */ protected final void setOutputParameters( final Statement cs, final Param[] params, final DatabaseResult result) throws Exception { CallableStatement tcs = (CallableStatement) cs; // get a count of outparams List outParamList = new ArrayList(); for (int i = 0; i < params.length; i++) { if (params[i].isOutParameter()) { OutParam outParam = new OutParam(); outParam.setId(params[i].getId()); outParam.setName(params[i].getName()); outParam.setType(params[i].getType()); String outParamSymbol = SymbolTable.removeSymbol(SymbolTable.OUT_PARAM + tcs.hashCode() + ":" + i + "}"); // get the value from the CallableStatement Object value = tcs.getObject(i + 1); if (value instanceof ResultSet) { // value is a resultset ResultSetBean rsb = new ResultSetBean((ResultSet) value, 1); outParam.setValue(rsb); if (outParamSymbol != null) { SymbolTable.setObject(outParamSymbol, rsb); } } else if (params[i].getType().endsWith("STRUCT")) { // value is a user-defined type (UDT) StructBean sb = new StructBean(value); outParam.setValue(sb); if (outParamSymbol != null) { SymbolTable.setObject(outParamSymbol, sb); } } else { // value is a String IType type = TypeFactory.getInstance(params[i].getType()); outParam.setValue(type.toString(value)); if (outParamSymbol != null) { SymbolTable.setValue(outParamSymbol, type.toString(value)); } } outParamList.add(outParam); } } OutParam[] ops = new OutParam[outParamList.size()]; for (int i = 0; i < ops.length; i++) { ops[i] = (OutParam) outParamList.get(i); } result.setOutParams(ops); }
/** * Overrides the parent method to clear parameters in the DatabaseResult object. * * @param cs the Statement object. * @param params the array of Param objects. * @exception Exception if there was a problem clearing the out parameters. */ protected final void clrOutputParameters(final Statement cs, final Param[] params) throws Exception { CallableStatement tcs = (CallableStatement) cs; for (int i = 0; i < params.length; i++) { if (params[i].isOutParameter()) { SymbolTable.removeSymbol(SymbolTable.OUT_PARAM + tcs + ":" + i + "}"); } } }
/** * Runs the SQL Stored Procedure contained in the call tag in the input XML file. Returns a * DatabaseResult object. * * @param elCall the JDOM Element representing the call tag. * @return the DatabaseResult returned from executing the stored procedure. * @exception Exception if there was a problem running the SQL. */ public final Object process(final Element elCall) throws Exception { LOG.debug(">> process()"); if (elCall == null) { throw new SQLUnitException(IErrorCodes.ELEMENT_IS_NULL, new String[] {"call"}); } String connectionId = XMLUtils.getAttributeValue(elCall, "connection-id"); // get the sql statement Element elStmt = elCall.getChild("stmt"); String callSql = XMLUtils.getText(elStmt); callSql = SymbolTable.replaceVariables(callSql); // get arguments List elParamList = elCall.getChildren("param"); Param[] params = new Param[elParamList.size()]; if (params.length > 0) { for (int i = 0; i < params.length; i++) { Element elParam = (Element) elParamList.get(i); IHandler paramHandler = HandlerFactory.getInstance(elParam.getName()); params[i] = (Param) paramHandler.process(elParam); } } // use the code in the superclass (which is a sequence of protected // method calls) and override only the portions that we need below). return executeSQL(connectionId, callSql, params); }