问题
I am using NamedParameterJdbcTemplate for run pl/sql script. But I don't know how can I get the values of out variables (:id_out). Thanks in advance.
String script = "declare
begin
if myFunc(:id_in) is null then
:id_out := 0;
else
:id_out := 1;
end if;
end;";
Map<String,Object> bindVars = new HashMap<String, Object>();
bindVars.put(id_in,1);
bindVars.put(id_out,2);
jdbcTmpl.execute(script, bindVars, new PreparedStatementCallback<Object>() {
@Override public Object doInPreparedStatement(PreparedStatement cs)
throws SQLException, DataAccessException {
cs.execute();
return null;
}
}
);
回答1:
I don't believe you can use a NamedParameterJdbcTemplate (or any other subclass of JdbcTemplate) with anonymous PL/SQL blocks such as that above. You'll have to wrap your anonymous PL/SQL block into a stored procedure or function.
Spring is intended to be portable across databases. As far as I know, neither MySQL nor SQL Server have a concept analogous to Oracle's anonymous PL/SQL blocks (I'm happy to be proved wrong on this point, though). Since this feature isn't portable across databases, Spring can't really support it for just Oracle.
回答2:
It can be done with a plain JdbcTemplate as in the following example, but note the way that the OUT value must be specified in the anonymous plsql block with "? := 'something';
java parameters used below: String id="12345" and String fixSql=
declare
p_id VARCHAR2(20) := null;
p_status_message VARCHAR2(32767) := null;
begin
p_id := ?;
p_status_message := ' Everything is possible: ' || p_id;
? := 'Return text.' || p_status_message;
end;
Note the two question marks above - the first is effectively an IN parameter and the second an OUT parameter. This code will call it:
public class Foo extends JdbcDaoSupport {
...
public String doAnonymousPlSql(final String id, String fixSql) throws CustomerFixException {
String resultValue = getJdbcTemplate().execute(new CallableStatementCreator() {
@Override
public CallableStatement createCallableStatement(Connection connection) throws SQLException {
CallableStatement sql = connection.prepareCall(fixSql);
sql.setString(1, id);
sql.registerOutParameter(2, Types.VARCHAR);
return sql;
}
}
, new CallableStatementCallback<String>() {
@Override
public String doInCallableStatement(CallableStatement callablestatement) throws SQLException,
DataAccessException {
callablestatement.executeUpdate();
return (String) callablestatement.getObject(2);
}
});
回答3:
List<SqlParameter> params = new LinkedList<SqlParameter>();
params.add(new SqlParameter(Types.NUMERIC));
params.add(new SqlParameter(Types.NUMERIC));
params.add(new SqlOutParameter("out_param_1", Types.NUMERIC));
params.add(new SqlOutParameter("out_param_2", Types.NUMERIC));
Map<String, Object> ret = simpleJdbcTemplate.getJdbcOperations().call(
new CallableStatementCreator() {
@Override
public CallableStatement createCallableStatement(Connection con) throws SQLException {
CallableStatement cs = con.prepareCall("DECLARE ..." +
"BEGIN ... " +
"delete from table where table_field_1 = ? and table_field_2 = ? " +
"returning out_param_1, out_param_2 into ?, ?; " +
"END;"
cs.setInt(1, first_in_param_value);
cs.setInt(2, second_in_param_value);
cs.registerOutParameter(3, Types.NUMERIC);
cs.registerOutParameter(4, Types.NUMERIC);
return cs;
}
}, params);
ret.get("out_param_1");
ret.get("out_param_1");
来源:https://stackoverflow.com/questions/9247430/spring-jdbc-template-how-can-get-outcome-variables-of-the-pl-sql-script