H2数据库中的存储过程

16

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

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

如何在H2中创建存储过程

在h2database链接中提供的示例代码,

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

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

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

此外,在H2中是否有以下语句的等效语句?

"begin dbms_output" ?

谢谢。


你有阅读文档吗?你所发布的语句是SQL语句,你需要使用JDBC API来执行它。 - Thomas Mueller
我想知道如何使用API调用它。任何示例代码参考都将非常有帮助。这个SQL部分应该在哪里声明?我知道这可能非常基础,但我刚开始学习。谢谢。 - Abi
我认为我的200分赏金已经浪费了,因为我意识到H2实际上不支持存储过程,Derby也是如此。这些只支持函数,而函数不能用于插入/更新/删除操作。可以在此功能和存储过程比较中看到。http://wiki.apache.org/db-derby/DerbySQLroutines :( - Airy
@AbdulJabbarWebBestow:我扩展了我的先前的回答 - trashgod
5个回答

14

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

1
我认为你忘记了 rs.next() - Thomas Mueller
@ThomasMueller H2数据库还是不支持存储过程吗?请查看我在问题评论部分的最后一条评论。是正确的还是错误的? - Airy
1
@AbdulJabbarWebBestow H2始终支持存储过程...也许您对存储过程的定义与我的定义不同?您的定义是什么?是否指与Oracle完全兼容的内容?是的,H2与Oracle不是100%兼容。 - Thomas Mueller
相关示例可在SQL语法:CREATE ALIAS中查看。 - trashgod

12

您可能忽略了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));

控制台:版本:1.4.191

补充说明:该功能不仅限于函数;别名方法可以执行任意Java代码。例如,在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));
}

控制台:用户:SA

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


感谢 @trashgod (+1) - 终于,一个调用Java函数作为别名的完整示例。 - smeeb

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()");

1

0

H2 不支持存储过程。我们可以创建一个函数来代替存储过程,该函数返回类似于存储过程的输出。就像我们在 registerInOut 参数中使用的一样。

例如,如果您的 QueryConst 如下所示:

public static final String INSERT_EMPLOYEE = "{call INSERT_EMPLOYEE(?,?,?)}";

那么,

我们可以使用 schema.sql(在 @Test 之前执行)。

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;
    

以及其他依赖项...(如果有的话)

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接