Spring JDBC 模板。如何获取pl/sql脚本的结果变量

发布于 2025-01-04 08:57:57 字数 809 浏览 0 评论 0原文

我正在使用 NamedParameterJdbcTemplate 来运行 pl/sql 脚本。 但我不知道如何获取 out 变量的值 (:id_out)。 提前致谢。

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;
                }
       }
       );

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;
                }
       }
       );

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我三岁 2025-01-11 08:57:58

可以使用普通 JdbcTemplate 来完成,如下例所示,但请注意必须在匿名 plsql 块中使用“? := 'something';

下面使用的 java 参数指定 OUT 值:String id="12345" 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;

请注意上面的两个问号 - 第一个实际上是 IN 参数,第二个是 OUT 参数。此代码将调用它:

    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);
            }
        });

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);
            }
        });
对你而言 2025-01-11 08:57:58

我不相信您可以将 NamedParameterJdbcTemplate (或 JdbcTemplate 的任何其他子类)与如上所述的匿名 PL/SQL 块一起使用。您必须将匿名 PL/SQL 块包装到存储过程或函数中。

Spring 旨在跨数据库移植。据我所知,MySQL 和 SQL Server 都没有类似于 Oracle 匿名 PL/SQL 块的概念(不过,我很高兴在这一点上被证明是错误的)。由于此功能不能跨数据库移植,因此 Spring 无法真正仅针对 Oracle 支持它。

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.

小伙你站住 2025-01-11 08:57:58
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");
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");
一曲爱恨情仇 2025-01-11 08:57:58

这在 Spring Data 中工作得很好:

NamedParameterJdbcTemplate jdbcTemplate;
jdbcTemplate.update(
    "DECLARE ... BEGIN ... (PL/SQL Block with named binding parameters) END;",
    new MapSqlParameterSource
        .addValue("parameter1", value1)
        .addValue("parameter2", value2));

This works fine in Spring Data:

NamedParameterJdbcTemplate jdbcTemplate;
jdbcTemplate.update(
    "DECLARE ... BEGIN ... (PL/SQL Block with named binding parameters) END;",
    new MapSqlParameterSource
        .addValue("parameter1", value1)
        .addValue("parameter2", value2));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文