【问题标题】:Stored Procedure in H2 DatabaseH2数据库中的存储过程
【发布时间】:2012-07-27 23:10:19
【问题描述】:

我是数据库新手,最近开始为 H2 数据库编写测试用例。 我想知道如何在 Eclipse 中测试存储过程。我看到了以下内容:

http://www.h2database.com/html/features.html#user_defined_functions

How to CREATE PROCEDURE in H2

h2database链接中给出的示例代码,

"CREATE ALIAS NEXT_PRIME AS $$
String nextPrime(String value) {
    return new BigInteger(value).nextProbablePrime().toString();
}
$$;
" 
  • 应该在哪里声明?如何运行?

PS - 我有 H2 JAR 文件并正在测试它。

如果有人能告诉我如何用Java为H2编写一个简单的存储过程,那将有很大帮助。

H2 中是否还有以下等效项?

“开始 dbms_output”?

谢谢。

【问题讨论】:

  • 您阅读文档了吗?您发布的语句是 SQL 语句,您需要使用 JDBC API 执行它。
  • 我想知道如何使用 API 调用它。任何示例代码参考都会有很大帮助。应该在哪里声明这个 SQL 部分?我知道这可能非常初级,但我才刚刚开始。谢谢
  • 我认为我的 200 点赏金已经浪费了,因为我意识到 H2 实际上不支持存储过程,Derby 也不支持。这些支持函数和函数不用于插入/更新/删除目的。从这个函数和存储过程的比较中可以看出。 wiki.apache.org/db-derby/DerbySQLroutines :(
  • @AbdulJabbarWebBestow:我扩展了我的previous answer

标签: java stored-procedures h2


【解决方案1】:
H2 DB is not supporting for storedprocs. In place of stored proc we have to create function which returns some output jst like storedproc as we did using registerInOut params. For example,

if ur QueryConst is like this:
public static final String INSERT_EMPLOYEE = "{call INSERT_EMPLOYEE(?,?,?)}";

then,

In our schema.sql(which executes @Test before)
DROP ALIAS IF EXISTS INSERT_EMPLOYEE;
CREATE ALIAS INSERT_EMPLOYEE FOR "com.test.EmployeeDaoImplTest.updateEmpStoredproc";


package com.test;
@ContextConfiguration(locations = { "classpath:configxmltest.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
@Sql(scripts = { "classpath:schema.sql" }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
public class EmployeeDaoImplTest {
    
    public static final String INSERT_EMPLOYEE = "{call INSERT_EMPLOYEE(?,?,?)}";


    @Autowired
    EmployeeDaoImpl employeeDaoTest;
    
    and other dependencies....(if any)

    @Test
    public void testUpdateEmployee() {
        ..ur logic if any input data settings
        assertEquals("Inserted Successfully", employeeDaoTest.updateEmployee(input, INSERT_EMPLOYEE));
    }

    public static ResultSet updateEmpStoredproc(String name, String w, Integer i) throws SQLException {
        SimpleResultSet rs = new SimpleResultSet();
        rs.addColumn("input", Types.VARCHAR, 255, 0);
        rs.addColumn("error", Types.VARCHAR, 255, 0);
        rs.addColumn("count", Types.INTEGER, 10, 0);
        rs.addRow(0, "Inserted Successfully");
        rs.addRow(1, 10);
        return rs;
    }
  }

【讨论】:

    【解决方案2】:

    您可能忽略了src/test/org/h2/samples/Function.java 中的示例。这是一个相关的例子:

    Connection conn = DriverManager.getConnection("jdbc:h2:mem:", "sa", "");
    Statement st = conn.createStatement();
    st.execute("CREATE ALIAS getVersion FOR \"org.h2.engine.Constants.getVersion\"");
    ResultSet rs;
    rs = st.executeQuery("CALL getVersion()");
    if (rs.next()) System.out.println("Version: " + rs.getString(1));
    

    控制台:Version: 1.4.191

    附录:特性不限于功能;别名方法可以执行任意Java code。例如,Function.java中定义的query()方法可能会被别名调用,如下所示:

    Connection conn = DriverManager.getConnection("jdbc:h2:mem:", "sa", "");
    Statement st = conn.createStatement();
    st.execute("CREATE ALIAS query FOR \"cli.Function.query\"");
    rs = st.executeQuery("CALL query('SELECT NAME FROM INFORMATION_SCHEMA.USERS')");
    while (rs.next()) {
        System.out.println("User: " + rs.getString(1));
    }
    

    控制台:User: SA

    请注意,cli.Function.queryorg.h2.samples.Function.query 的副本。

    【讨论】:

    • 感谢@trashgod (+1) - 终于,一个完整的调用 Java 函数作为别名的示例。
    【解决方案3】:

    以下是我们过去在项目中实施的方式。这可能会有所帮助:)

    package com.procedures;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class CRITICAL_ACTIONS {
    
        public static final int SAVE_ACTION(Connection connection) throws SQLException {
            try {
                Statement statement = connection.createStatement();
                return statement.executeUpdate("INSERT INTO SCHEMA1.CRITICAL_ACTIONS(COLLEAGUE_ID,JOURNEY_ID,TYPE,PRODUCT,DESCRIPTION,META_DATA,STATUS) values('12345',11111111,'ABC','Lloyds','hellow','hello','START')");
            } finally {
                //connection.close();
            }
        }
    
        public static final ResultSet FETCH_ACTION(Connection connection) throws SQLException {
            try {
                Statement statement = connection.createStatement();
                return statement.executeQuery("SELECT * FROM SCHEMA1.CRITICAL_ACTIONS");
            }finally {
                connection.close();
            }
        }
    
    
    }
    

    在 Java 中调用 H2 Java 存储过程:-

        jdbcTemplate.update("CREATE ALIAS SAVE_ACTION FOR \"com.procedures.CRITICAL_ACTIONS.SAVE_ACTION\"");
        jdbcTemplate.update("CREATE ALIAS FETCH_ACTION FOR \"com.procedures.CRITICAL_ACTIONS.FETCH_ACTION\"");
    
        jdbcTemplate.getDataSource().getConnection().createStatement().execute("call SAVE_ACTION()");
    

    【讨论】:

      【解决方案4】:

      H2数据库中的存储过程和java方法一样,所以写java方法,可以用别名调用。

      【讨论】:

        【解决方案5】:

        H2数据库中没有存储过程和sql用户定义函数,我们使用java方法并创建一个别名来引用它。我们可以使用别名调用该方法。

        下面是一个简单的例子:**

        DROP ALIAS IF EXISTS MYFUNCTION;
        CREATE ALIAS MYFUNCTION AS $$
        String getTableContent(java.sql.Connection con) throws Exception {
            String resultValue=null;
            java.sql.ResultSet rs = con.createStatement().executeQuery(
            " SELECT * FROM TABLE_NAME");
               while(rs.next())
               {
                resultValue=rs.getString(1);
               }
            return resultValue;
        }
        $$;
        

        【讨论】:

        • 我想你忘了rs.next()
        • @ThomasMueller H2 仍然不支持存储过程吗?请在问题评论部分查看我的最后评论。是对还是错?
        • @AbdulJabbarWebBestow H2 始终支持存储过程...也许您对存储过程的定义与我的定义不同?你的定义是什么?与 Oracle 100% 兼容的东西?是的,H2 并非 100% 兼容 Oracle。
        • 相关示例见SQL Grammar: CREATE ALIAS
        猜你喜欢
        • 1970-01-01
        • 2011-03-07
        • 2019-07-03
        • 1970-01-01
        • 1970-01-01
        • 2017-06-16
        • 2017-07-24
        • 1970-01-01
        • 2019-12-14
        相关资源
        最近更新 更多