查询以输出查询、表或视图的列名和数据类型

vfc*_*sts 26 postgresql datatypes catalogs fields

是否有 PostgreSQL 查询或命令返回查询、表或视图的字段名称和字段类型?

例如,如果应用于简单的 SELECT 查询的解决方案SELECT * from person应该返回如下列表:

Column Name   | Column Type
===========================
First Name    | character
Last Name     | character
Age           | integer
Date of Birth | date
Run Code Online (Sandbox Code Playgroud)

我查看了information_schema下面的答案中描述的视图,它似乎很好地涵盖了表格,我怀疑它也涵盖了视图,但我还没有检查过。

最后一个是任意但有效的 SELECT 查询,例如涉及数据库中的JOINSUNIONS等。是否有内置过程或其他存储过程或脚本可以为任何有效的 QUERY 返回相同的结果?

我正在开发一个程序来创建数据和查询表单,数据验证和对返回的数据执行函数需要这些信息。

Erw*_*ter 29

信息模式系统目录

我们已经多次讨论过这个问题。信息模式服务于某些目的。如果您了解系统目录的方式,那么这些目录可以更好地用于大多数目的,IMO。系统目录是所有信息的实际来源。

信息架构提供了标准化的意见,帮助与便携性,主要是跨主要的Postgres版本,因为在不同的关系型数据库平台的可移植性通常是一种假象,一旦你的查询是复杂的,足以需要查找系统目录。而且,值得注意的是,Oracle 仍然不支持信息模式。

信息模式中的视图必须跳过许多环节才能达到符合标准的格式。这使它们变慢,有时非常慢。比较这些基本对象的计划和性能:

EXPLAIN ANALYZE SELECT * from information_schema.columns;
EXPLAIN ANALYZE SELECT * from pg_catalog.pg_attribute;
Run Code Online (Sandbox Code Playgroud)

差异是显着的。这真的取决于你在寻找什么。

你的榜样

对于您的示例SELECT * from tbl,请比较下面这个简单表的两个查询:

CREATE TEMP TABLE foo(
   A numeric(12,3)
 , b timestamp(0)
);
Run Code Online (Sandbox Code Playgroud)

使用pg_attribute

SELECT attname, format_type(atttypid, atttypmod) AS type
FROM   pg_attribute
WHERE  attrelid = 'foo'::regclass
AND    attnum > 0
AND    NOT attisdropped
ORDER  BY attnum;
Run Code Online (Sandbox Code Playgroud)

format_type() 返回带有所有修饰符的完整类型:

attname | type
--------+-------------------------------
a       | numeric(12,3)
b       | timestamp(0) without time zone
Run Code Online (Sandbox Code Playgroud)

另请注意,转换为regclass根据当前search_path. 如果名称无效,它也会引发异常。细节:

使用information_schema.columns

SELECT column_name, data_type
FROM   information_schema.columns
WHERE  table_name = 'foo'
ORDER  BY ordinal_position;
Run Code Online (Sandbox Code Playgroud)

信息是标准化的,但不完整

column_name | data_type
------------+----------------------------
a           | numeric
b           | timestamp without time zone
Run Code Online (Sandbox Code Playgroud)

要获得数据类型的完整信息,您需要额外考虑所有这些列:

character_maximum_length
character_octet_length
numeric_precision
numeric_precision_radix
numeric_scale
datetime_precision
interval_type
interval_precision
Run Code Online (Sandbox Code Playgroud)

相关回答:

利弊列表,最大的优点(IMO)以粗体显示:

信息架构视图

  • 通常更简单(取决于)
  • 减缓
  • 预处理,这可能适合也可能不适合您的需要
  • 选择性(用户只能看到他们有权访问的对象)
  • 符合 SQL 标准(由一些主要的 RDBMS 实现)
  • 主要可移植到主要 Postgres 版本
  • 不需要太多关于 Postgres 的具体知识
  • 标识符是描述性的,很长,有时很尴尬

系统目录

  • 通常更复杂(取决于),更接近源
  • 快速地
  • 完整oid包括系统列)
  • 不符合 SQL 标准
  • 跨主要 Postgres 版本的可移植性较差(但基础不会改变)
  • 需要更多关于 Postgres 的具体知识
  • 标识符简洁、描述性较差但方便简短

任意查询

要从查询中获取相同的列名和类型列表,您可以使用一个简单的技巧:从查询输出中创建一个临时表,然后使用与上述相同的技术。

您可以 append LIMIT 0,因为您不需要实际数据:

CREATE TEMP TABLE tmp123 AS
SELECT 1::numeric, now()
LIMIT  0;
Run Code Online (Sandbox Code Playgroud)

要获取单个列的数据类型,您还可以使用函数pg_typeof()

SELECT pg_typeof(1);
Run Code Online (Sandbox Code Playgroud)