如何列出指定表的所有列


292

我正在数据库中寻找我不了解的精确信息。

这是第三方产品,他们回答某些问题的速度很慢,而且我知道数据位于该数据库内部,所以我想做一些复古工程。

给定一个表,是否可以列出该表的列名?

例如,在SqlServer中,可以将表转储到可重用的CREATE语句中,该语句以文本形式列出表所组成的所有列。


您对数据库有什么样的访问权限?
dezso 2012年

@dezso,它在单独的机器上,但是我可以登录到它,并以管理员权限启动psql命令行
Stephane Rolland 2012年

6
如果我对您的理解正确,则您在\dt[+] table_namepsql
dezso 2012年

1
不。\ dt +似乎没有明确显示列名。它仅添加一个“描述”字段。
Stephane Rolland

12
但是\ d +表名有效!
Stephane Rolland

Answers:


344

除了\d+ <table_name>已经找到的命令行之外,还可以使用Information Schema通过以下命令来查找列数据information_schema.columns

SELECT *
  FROM information_schema.columns
 WHERE table_schema = 'your_schema'
   AND table_name   = 'your_table'
     ;

注意:按照上面的示例,请确保将值括在引号中。


2
在psql中,使用\x on\pset expanded on使查询结果线性(而不是表格),从而更易于阅读stackoverflow.com/a/9605093/513397
anishpatel

4
在当前版本中(在9.6中进行了尝试),您可以在psql中进行操作\d+ public.*以获取模式中所有表和视图的描述(模式+ indeces / fkeys / triggers)public。我们在预提交的钩子脚本中使用它来跟踪git每次提交对数据库所做的更改。
塔利斯K.17年

4
SELECT column_name仅获得列名
Andrew

82

作为对其他答案的补充,即使是不返回任何行的SELECT语句,也会向您和应用程序代码显示列名。

select *
from table_name
where false;

这些方法中的任何一种都可能会引起许可。


我想您的意思是将此SQL传递给psql命令。我建议在这种情况下使用--no-psqlrc选项,以避免输出出现意外情况。
JohnMudd

除了必须指定要选择的隐藏列之外(如pg_class.oid)
okutane

71

信息模式是慢而稳的方式:它是标准化的,基本上可以移植到支持它的其他数据库。而且它将在主要版本之间继续工作。

但是,信息模式中的视图通常会加入系统目录中的许多表中,以符合严格标准化的格式-大多数情况下,其中许多只是空载。这使它们变慢
Postgres开发人员并未做出承诺,但基础知识(如此处所需的内容)不会在主要版本之间发生变化。

psql(本机命令行界面)当然会走快速通道,并直接查询源。如果psql以参数-E开头\d则会显示反斜杠命令之类的SQL 。或\set ECHO_HIDDEN on从psql命令行。从那里开始,您可以建立问题的答案。

给定一个表,可以列出该表的列名称。

SELECT attrelid::regclass AS tbl
     , attname            AS col
     , atttypid::regtype  AS datatype
       -- more attributes?
FROM   pg_attribute
WHERE  attrelid = 'myschema.mytable'::regclass  -- table name, optionally schema-qualified
AND    attnum > 0
AND    NOT attisdropped
ORDER  BY attnum;

查询information_schema.columns快。尝试EXPLAIN ANALYZE自己看看。一次性查找仍然无关紧要。但是,如果在多次重复的查询/函数中使用,可能会有所不同。

可见性也有细微的差异。详细比较:


2
确实如此,您向您-E展示并向人们展示如何获取psql的sql。
埃文·卡罗尔

6

psql 在PostgreSQL 11+上

如果要查找查询的列类型,则可以使用psql\gdesc

SELECT
    NULL AS zero,
    1 AS one,
    2.0 AS two,
    'three' AS three,
    $1 AS four,
    sin($2) as five,
    'foo'::varchar(4) as six,
    CURRENT_DATE AS now
\gdesc
 Column |         Type         
--------+----------------------
 zero   | text
 one    | integer
 two    | numeric
 three  | text
 four   | text
 five   | double precision
 six    | character varying(4)
 now    | date
(8 rows)

0

仅PostgreSQL

这有点曲折,但是如果您正在寻找最短的SQL,则可能是一个竞争者:

SELECT json_object_keys(to_json(json_populate_record(NULL::schema_name.table_name, '{}'::JSON)))

甚至更短(假设表中至少存在一行)

SELECT json_object_keys(to_json((SELECT t FROM schema_name.table_name t LIMIT 1)))

清单保留订单。如果您不在乎订单并安装了hstore扩展程序,则可以做得更短

SELECT skeys(hstore(NULL::schema_name.table_name))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.