我使用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 = ?
但它返回空 ResultSet
(rs.next()
为false)。
使用SELECT
时我做错了什么?
我使用JDK7中包含的derby.jar
。
这是我的代码:
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:
未打印,因此仍然无效。
答案 0 :(得分:1)
在derby-user邮件列表中讨论了该问题,其中包含了on commit preserve rows
的附加要求。
启用autocommit时,默认情况下会在提交时清除临时表,因此extra子句可确保在事务提交之后保持行可用。
答案 1 :(得分:0)
这里使用两个概念,一个是带有In-Memors存储选项的Derby,另一个是临时表。如果需要In-Memors数据库,仍可以使用常规定义的表(“CREATE TABLE ...”)。这将使您更容易,因为您不必处理这些临时表的会话语义。
答案 2 :(得分:-2)
你应该真正关注Hibernate。它不仅可以映射您的类,还可以为您管理讨厌的JDBC内容,因此您可以专注于您想要完成的任务。它远非完美,但除此之外,它还为您提供了数据库可移植性。
我通过Spring使用hibernate,所以我的代码看起来像:
TempStorage temp = new TempStorage();
temp.setName("Bob");
getHibernateTemplate.insert(temp);
temp = getHibernateTemplate.find("SELECT name FROM TempStorage");