我正在用 Java 编写一个数据库程序,如果它不存在,我想创建一个表。我DatabaseMetaData.getTables()
从如何在 Java 中检测 SQL 表的存在?我正在尝试使用它:
private boolean tableExists() throws SQLException {
System.out.println("tableExists()");
DatabaseMetaData dbmd = conn.getMetaData();
ResultSet rs = dbmd.getTables(null, null, this.getTableName(), null);
System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME"));
return rs.getRow() == 1;
}
问题是rs.getRow()
总是返回0
,即使在创建表之后也是如此。Usingrs.getString("TABLE_NAME")
会抛出一个异常,指出结果集为空。
我想到的一种可能的解决方案是执行CREATE TABLE
语句并捕获抛出的任何异常。但是,我不喜欢在程序的控制流中使用异常的想法。
FWIW,我正在使用 HSQLDB。但是,我想编写独立于 RDMS 引擎的 Java 代码。还有另一种方法可以DatabaseMetaData.getTables()
用来做我想做的事吗?还是有其他解决方案来编写我的tableExists()
方法?
添加:
使用此处给出的建议,我找到了一个似乎适用于我的生产代码的解决方案:
private void createTable() throws SQLException {
String sqlCreate = "CREATE TABLE IF NOT EXISTS " + this.getTableName()
+ " (brand VARCHAR(10),"
+ " year INTEGER,"
+ " number INTEGER,"
+ " value INTEGER,"
+ " card_count INTEGER,"
+ " player_name VARCHAR(50),"
+ " player_position VARCHAR(20))";
Statement stmt = conn.createStatement();
stmt.execute(sqlCreate);
}
现在我还在编写一个 JUnit 测试来断言该表确实已创建:
public void testConstructor() throws Exception {
try (BaseballCardJDBCIO bcdb = new BaseballCardJDBCIO(this.url)) {
String query = "SELECT count(*) FROM information_schema.system_tables WHERE table_name = '" + bcdb.getTableName() + "'";
Connection conn = DriverManager.getConnection(this.url);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
Assert.assertTrue(rs.next());
Assert.assertEquals(1, rs.getInt(1));
Assert.assertFalse(rs.next());
}
}
此测试失败assertEquals()
并显示以下消息:
FAILED: expected: <1> but was: <0>