从jdbc / postgresql获取新创建的表的列元数据

时间:2014-03-05 07:49:06

标签: java postgresql jdbc

我正在尝试从新创建的表中获取列列表(它是在java代码中创建的)。 问题是我没有得到专栏。 该代码适用于已存在于数据库中的表,但如果我创建一个新的并尝试立即获取列信息,则它找不到任何...

更新: 这是我用于测试的完整代码:

@Test
public void testtest() throws Exception {
    try (Connection conn = dataSource.getConnection()) {
        String tableName = "Table_" + UUID.randomUUID().toString().replace("-", "");
        try (Statement statement = conn.createStatement()) {
            statement.executeUpdate(String.format("create table %s (id int primary key,name varchar(30));", tableName));
        }
        DatabaseMetaData metaData = conn.getMetaData();
        try (ResultSet rs = metaData.getColumns(null, null, tableName, null)) {
            int colsFound = 0;
            while (rs.next()) {
                colsFound++;
            }
            System.out.println(String.format("Found %s cols.", colsFound));
        }
        System.out.println(String.format("Autocommit is set to %s.", conn.getAutoCommit()));
    }
}

和输出:

Found 0 cols.
Autocommit is set to true.

3 个答案:

答案 0 :(得分:5)

问题在于你的tablename:

String tableName = "Table_" 

因为这是一个不带引号的标识符(一件好事),当Postgres将其名称存储在系统目录中时,名称将转换为小写。

DatabaseMetaData API调用区分大小写("Table_"!= "table_"),因此您需要传递小写的表名:

ResultSet rs = metaData.getColumns(null, null, tableName.toLowerCase(), null))

有关标识符使用方式的更多详细信息,请参阅手册:http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS

答案 1 :(得分:1)

我做了简单的测试,似乎有效。我可以使用PostgreSQL JDBC创建新表并显示其列(我使用Jython):

conn = db.createStatement()
conn.execute("CREATE TABLE new_table (id SERIAL, txt VARCHAR(200))")
db_meta_data = db.getMetaData()
for tbl_name in ('date_test', 'new_table'):
    print('\n-- %s --' % (tbl_name))
    rs = db_meta_data.getColumns(None, None, tbl_name, None)
    while (rs.next()):
        print('%s:%s' % (rs.getString(3), rs.getString(4)))
conn.close()

此代码显示已存在的表的列:date_test和刚刚创建的new_table。我还添加了一些代码以在CREATE TABLE之后关闭连接,但我的结果总是相同且正确。

可能是你的JDBC驱动程序有问题。我使用来自postgresql-9.3-1100.jdbc41.jar的驱动程序。

用户权限也可能存在问题。您是否使用相同的用户创建表和获取元数据?新表格在psqlpgAdmin或其他工具中是否可见?

其他原因是PostgreSQL也使用事务进行架构更改。因此,如果禁用默认自动提交和关闭连接,则架构更改将丢失。你使用db.setAutoCommit(false)吗?

您也可以直接查询PostgreSQL架构:

SELECT DISTINCT table_name, column_name
FROM information_schema.columns
WHERE table_schema='public'
AND table_name = 'new_table'
ORDER BY 1, 2 

答案 2 :(得分:0)

奇怪地以小写的方式将表格名称传递给getColumns方法确实有效...感谢查询MichałNiklas让我走上了正确的轨道。