H2:如何使用out参数创建存储过程

时间:2018-01-05 21:31:29

标签: java stored-procedures h2 out-parameters

我正在尝试使用Spring(非启动)配置的JUnit测试中创建带有out参数的存储过程。我从文档和示例中了解到,我必须使用静态方法来对应用存储过程调用进行别名。但是,我没有提到它如何与out parameters一起使用。静态方法的方法签名是什么?

package com.example;

import static java.sql.Types.INTEGER;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.h2.tools.SimpleResultSet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { H2tests.TestConfiguration.class })
public class H2tests {

    @Autowired
    DataSource dataSource;

    public static ResultSet executeMyProc(int a) {

        return new SimpleResultSet();
    }

    // what should the type of the second parameter be?
    public static ResultSet executeMyProc(int a, int b) {

        return new SimpleResultSet();
    }

    @Test // passes
    public void worksWithInParam() throws SQLException {

        final CallableStatement stmt = dataSource.getConnection().prepareCall("CALL my_proc(?)");
        stmt.setInt(1, 44);
        stmt.executeQuery();
    }

    @Test // fails
    public void worksWithOutParam() throws SQLException {

        final CallableStatement stmt = dataSource.getConnection().prepareCall("CALL my_proc(?, ?)");
        stmt.setInt(1, 999);
        stmt.registerOutParameter(2, INTEGER);
        stmt.executeQuery();
    }

    public static class TestConfiguration {

        @Bean
        public DataSource dataSource() throws SQLException {

            final EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
            final EmbeddedDatabase db = builder //@formatter:off
                    .setType(EmbeddedDatabaseType.H2)
                    .setName("MODE=MySQL")
                    .build(); //@formatter:on
            db.getConnection().prepareStatement("CREATE ALIAS my_proc FOR \"com.example.H2tests.executeMyProc\"")
                    .execute();
            return db;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我认为H2不支持参数。您必须通过结果集返回值:

public static ResultSet hello(String name)
{
    SimpleResultSet result = new SimpleResultSet();
    result.addColumn("GREETING", Types.VARCHAR, 255, 0);
    result.addRow("Hello, " + name + "!");
    return result;
}

@Test
public void test() throws Exception
{
    Connection connection = DriverManager.getConnection("jdbc:h2:mem:");
    Statement statement = connection.createStatement();
    statement.execute("CREATE ALIAS hello FOR \"DatabaseTest.hello\"");
    ResultSet resultSet = statement.executeQuery("CALL hello('Bart')");
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getString("GREETING"), is("Hello, Bart!"));
}