【问题标题】:How to get column names and types from a PostgreSQL query (without running it)?如何从 PostgreSQL 查询中获取列名和类型(不运行它)?
【发布时间】:2017-06-25 05:44:00
【问题描述】:

对于任何给定的(Postgres)SQL 查询,我需要能够提取列名和列类型。我不需要查询的结果。而且我需要它快速(即我不想等待查询本身完成 - 特别是如果它需要几分钟或更长时间)。

我认为我有一个解决方案:

提取以下查询的列和类型:

with X as (
  select nationality, count(*)
  from customers group by nationality
)
select *
from X

我将它包装如下:

select *
from (
    with X as (
        select nationality, count(*)
        from customers group by nationality
    )
    select *
    from X
) q
where 1 = 0
limit 0

where 1 = 0limit 0 意味着它不会运行内容。

但它不起作用

如果customers 表很大,那么上面的运行需要一分钟。然后返回 0 个结果(如预期的那样)。

有什么想法吗?

是否有任何方法(无需编写我自己的 PSQL 解析器)从任意 PSQL 查询中获取列名和类型(无需运行完成)?

注意:目标是让它与任意(用户输入的)SQL SELECT 查询一起工作。

【问题讨论】:

  • 这个例如可以使用 Java/JDBC 和 PreparedStatement(至少在 Postgres 中,我不知道 Redshift 驱动程序是否支持 - 这两者完全不同)
  • 是的,protocol 允许您在不实际执行任何操作的情况下获取 RowDescription,但您的客户端库是否公开这是另一个问题。
  • 嘿@a_horse_with_no_name。您如何使用 JDBC for Postgres 做到这一点?

标签: postgresql jdbc amazon-redshift


【解决方案1】:

给定一个作为字符串的 SQL 语句,你能不能在字符串中添加“LIMIT=0”并运行修改后的查询?当然,这只会获取列名,但这些可以用于查询类型的信息架构。

如果 SQL 已经包含限制,是否可以修改其参数?

【讨论】:

  • 不幸的是,这也不起作用。将限制设置为 0 或 1 仍然需要 2 分钟以上才能返回。
【解决方案2】:

使用 Postgres(及其 JDBC 驱动程序),您可以执行以下操作:

PreparedStatement pstmt = con.prepareStatement("select ... ");
ResultSetMetaData meta = pstmt.getMetaData();
for (int i=1; i <= meta.getColumnCount(); i++)
{
  System.out.println("Column name: " + meta.getColumnName(i) + ", data type: " + meta.getColumnTypeName(i));
}

请注意,您不需要在语句中添加where falselimit 0。对prepareStatement() 的调用实际上并未执行查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 2013-12-10
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    • 2014-11-29
    相关资源
    最近更新 更多