PostgreSQL - 从数据库表中提取列名、数据类型和样本值

Posted

技术标签:

【中文标题】PostgreSQL - 从数据库表中提取列名、数据类型和样本值【英文标题】:PostgreSQL - pull column name, data type, and sample value from database table 【发布时间】:2018-03-09 19:35:27 【问题描述】:

我想知道是否可以使用单个 PostgreSQL 查询从数据库表中提取列名、数据类型和一个示例值。我的目标是对一张表的所有列执行此操作。

感觉列名需要一个变量,因此您可以在查询表以获取示例值时使用它,但 Postgres 在普通 SQL 语句中不支持此功能 (How to declare a variable in a PostgreSQL query)。

我可以通过硬编码单个值来实现这一点,但是关于是否可以对表的每一列执行此操作的任何建议(在选择语句中使用其名称连接每个列以获得单个样本值)?

列 |数据类型 | sample_val
--------------------------------
foo_col1 |正文 | 
foo_col2 |正文 | 'foo_val2'
foo_col3 |正文 | 
select column_name as column, data_type, sample_val
from information_schema.columns t1
join pg_class t2 on (t1.table_name = t2.relname)
left outer join pg_description t3 on (t2.oid = t3.objoid and t3.objsubid = t1.ordinal_position)

left outer join (select CAST('foo_col2' AS text) as foo_col2, foo_col2 as sample_val from foo_schema.foo_table limit 1) n2
on (n2.foo_col2 = column_name)

where table_schema = 'foo_schema'
and table_name = 'foo_table'
order by ordinal_position

【问题讨论】:

【参考方案1】:

您可以为此使用row count for all tables 的变体:

select c.table_schema, c.table_name,
       c.column_name,
       c.data_type,
       (xpath('/table/row/'||column_name||'/text()', 
          query_to_xml(format('select %I 
                               from %I.%I limit 1', c.column_name, c.table_schema, c.table_name), true, false, '')))[1]::text as sample_value
from information_schema.columns c 
where table_schema = 'foo_schema';

query_to_xml() 将运行查询并将结果格式化为 XML。然后xpath() 函数从 XML 中提取该列值。

这是相当昂贵的,因为查询对每列运行一次,而不是对每个表运行一次。请注意,样本值可能不是来自同一行。

您可以通过对每个表运行一个查询然后将该结果连接回列来优化这一点:

with samples as (
  select table_schema, 
         table_name, 
         query_to_xml(format('select * from %I.%I limit 1', table_schema, table_name), true, false, '') as sample_row
  from information_schema.tables 
  where table_schema = 'foo_schema'
)
select c.table_schema, c.table_name,
       c.column_name,
       c.data_type,
       (xpath('/table/row/'||column_name||'/text()', s.sample_row))[1]::text as sample_value
from information_schema.columns c 
  join samples s on (s.table_schema, s.table_name) = (c.table_schema, c.table_name);

使用上述方法,所有样本值都来自同一行。

【讨论】:

感谢您的建议!绝对在正确的路径上,但是使用 xpath() 函数为您提供的语句解析 XML 时出错。试图弄清楚。使用这个版本的 Postgres:PostgreSQL 9.3.16 绝对可以将问题定位到 xpath() 函数调用,但仍停留在它的问题上。此查询给出了 sample_value 的 XML:select c.table_schema, c.table_name, c.column_name, c.data_type, query_to_xml(format('select %I from %I.%I limit 1', c.column_name, c.table_schema, c.table_name), true, true, '')::text as sample_value from information_schema.columns c where table_schema = 'foo_schema'; "<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <foo_col>1519598724863690</foo_col> </row>" 硬编码工作:with samples as ( select table_schema, table_name, query_to_xml(format('select * from %I.%I limit 1', table_schema, table_name), true, true, '') as sample_row from information_schema.tables where table_schema = 'foo_schema' ) select c.table_schema, c.table_name, c.column_name, c.data_type, (xpath('/row/foo_col/text()', s.sample_row))[1]::text as sample_value from information_schema.columns c join samples s on (s.table_schema, s.table_name) = (c.table_schema, c.table_name) where column_name = 'foo_col'; @AndrewGoss:这对我来说适用于 9.3,但仅适用于包含至少一行的表格。如果query_to_xml 的结果为空,则会收到错误“无法解析 XML 文档”。

以上是关于PostgreSQL - 从数据库表中提取列名、数据类型和样本值的主要内容,如果未能解决你的问题,请参考以下文章

如何从 BigQuery 表中提取所有列名的列表?

通过 JDBC 从 Spark 提取表数据时出现 PostgreSQL 错误

PostgreSQL 列名作为两个表中的关键字

如何从表中提取行,用不同的值过滤同一列?

ABAP从较大内表取部分数据到较小内表中 怎么取 可以按字段直接取数吗?

在空表中查找 SQLite 列名