2017-02-07 41 views
0

对于任何给定的(Postgres)SQL查询,我需要能够提取列名称和列类型。我不需要查询的结果。我需要它很快(即我不希望等待查询本身完成 - 特别是如果需要几分钟或更长的时间)。如何从PostgreSQL查询中获取列名和类型(不运行它)?

我想我有一个解决方案:

要提取列和类型下面的查询:

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

和:

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

我将如下把它包where 1 = 0limit 0意味着它不会运行内容。

但它不工作

如果customers表是巨大的,那么上述接管一分钟运行。然后返回0结果(如预期)。

任何想法?

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

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

+0

例如,可能用Java/JDBC和PreparedStatement(至少在Postgres中,我不知道Redshift驱动程序是否支持这个 - 这两个完全不同) –

+0

是的,[protocol](https://www.postgresql.org/ docs/8.0/static/protocol-flow.html#AEN56097)允许您在没有实际执行任何内容的情况下获取RowDescription,但您的客户端库是否暴露此问题是另一个问题。 –

+0

嘿@a_horse_with_no_name。你如何使用JDBC为Postgres做到这一点? –

回答

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()的调用并不实际执行查询。

+0

这有效。谢谢。对于红移也是如此。 –

0

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

如果SQL已经包含一个限制,它的参数可以被修改?

+0

这不幸也不起作用。设置0或1的限制仍然需要2分钟以上才能返回。 –

相关问题