3

我使用 JavaDB/Derby 创建了一个内存数据库表。我可以将INSERT数据放入表中。SELECT但是当我尝试从表中获取数据时它不起作用。

我用以下方法创建表:

DECLARE GLOBAL TEMPORARY TABLE SESSION.memtable (id int, name varchar(10))
NOT LOGGED

插入数据:

INSERT INTO SESSION.memtable (id, name) VALUES (?,?)

它返回1. rows affected选择数据:

SELECT name FROM SESSION.memtable WHERE id = ?

但它返回一个 ResultSetrs.next()是假的)。

使用时我做错了什么SELECT

我使用derby.jarJDK7中包含的那个。

这是我的代码:

public class DBTest {
    public static void main(String[] args) {
        final int userId = 4;
        final String sql = "DECLARE GLOBAL TEMPORARY TABLE SESSION.memtable "+
                            "(id int, name varchar(10)) NOT LOGGED";
        final String inSQL = "INSERT INTO SESSION.memtable (id, name) "+
                             "VALUES (?,?)";
        final String selSQL = "SELECT name FROM SESSION.memtable WHERE id = ?"
        final String connURL = "jdbc:derby:memory:memdatabase;create=true";
        try(Connection conn = DriverManager.getConnection(connURL);) {
            try (PreparedStatement ps = conn.prepareStatement(sql);) {
                ps.execute();
            }
            try (PreparedStatement ps = conn.prepareStatement(inSQL);) {
                ps.setInt(1, userId);
                ps.setString(2, "Jonas");
                int rows = ps.executeUpdate();
                System.out.println(rows + " rows inserted.");
            }
            try (PreparedStatement ps = conn.prepareStatement(selSQL);) {
                ps.setInt(1, userId);
                try (ResultSet rs = ps.executeQuery();) {
                    String name;
                    if(rs.next()) {
                        name = rs.getString("name");
                    } else {
                        name = null;
                    }
                    System.out.println("Name: " + name);
                }
            }
        } catch (SQLException e) {e.printStackTrace();}}}

更新

如果我将 SELECT 查询更改为:

SELECT t1.name AS name FROM SESSION.memtable t1 WHERE id = ?

我收到此错误消息:

java.sql.SQLException: Operation 'DROP TABLE' cannot be performed on object 'MEMTABLE(ID, NAME)' because there is an open ResultSet dependent on that object.
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.commitIfAutoCommit(Unknown Source)
    at org.apache.derby.impl.jdbc.ConnectionChild.commitIfAutoCommit(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedStatement.resultSetClosing(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedResultSet.movePosition(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedResultSet.next(Unknown Source)
    at DBTest.main(DBTest.java:29)
Caused by: java.sql.SQLException: Operation 'DROP TABLE' cannot be performed on object 'MEMTABLE(ID, NAME)' because there is an open ResultSet dependent on that object.
    at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
    ... 11 more
Caused by: ERROR X0X95: Operation 'DROP TABLE' cannot be performed on object 'MEMTABLE(ID, NAME)' because there is an open ResultSet dependent on that object.
    at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
    at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.verifyNoOpenResultSets(Unknown Source)
    at org.apache.derby.impl.sql.GenericPreparedStatement.prepareToInvalidate(Unknown Source)
    at org.apache.derby.impl.sql.depend.BasicDependencyManager.coreInvalidateFor(Unknown Source)
    at org.apache.derby.impl.sql.depend.BasicDependencyManager.invalidateFor(Unknown Source)
    at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.tempTablesAndCommit(Unknown Source)
    at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.doCommit(Unknown Source)
    at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.userCommit(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.commit(Unknown Source)
    ... 6 more

但是Name:没有打印,所以它仍然不起作用。

4

3 回答 3

1

该问题在derby-user邮件列表中进行了讨论,其中指出了要包含的附加要求on commit preserve rows

启用自动提交后,默认情况下会在提交时清除临时表,因此额外的子句确保行在事务提交之后保持可用。

于 2011-11-11T14:39:13.557 回答
0

您在这里使用了两个概念,一个是带有 In-Memors 存储选项的 Derby,另一个是临时表。如果您想要一个 In-Memors 数据库,您仍然可以使用常规定义的表(“CREATE TABLE ...”)。这将使它更容易,因为您不必处理这些临时表的会话语义。

于 2014-08-10T23:25:21.540 回答
-2

你真的应该研究一下Hibernate。它不仅映射您的类,而且为您管理令人讨厌的 JDBC 内容,因此您可以专注于您想要完成的事情。它远非完美,但最重要的是,它为您提供了数据库可移植性。

我通过 Spring 使用休眠,所以我的代码看起来像:

TempStorage temp = new TempStorage();
temp.setName("Bob");
getHibernateTemplate.insert(temp);
temp = getHibernateTemplate.find("SELECT name FROM TempStorage");
于 2011-11-11T12:35:20.893 回答