如何使用 PostgreSQL 从表名中获取列属性查询?
Posted
技术标签:
【中文标题】如何使用 PostgreSQL 从表名中获取列属性查询?【英文标题】:How to get column attributes query from table name using PostgreSQL? 【发布时间】:2013-04-10 14:04:31 【问题描述】:我有一个项目,我需要一个查询来使用表名获取列的所有属性(列名、位置、数据类型、Not Null?和评论)。
我实现了get Column Name, Position Data Type and Not Null?用这个查询:
SELECT column_name, data_type, ordinal_position, is_nullable
FROM information_schema."columns"
WHERE "table_name"='TABLE-NAME'
但是,我需要评论!
【问题讨论】:
【参考方案1】:这是针对 system catalog 的查询,它应该获取您需要的所有内容(免费提供一个额外的主键字段)。
SELECT DISTINCT
a.attnum as num,
a.attname as name,
format_type(a.atttypid, a.atttypmod) as typ,
a.attnotnull as notnull,
com.description as comment,
coalesce(i.indisprimary,false) as primary_key,
def.adsrc as default
FROM pg_attribute a
JOIN pg_class pgc ON pgc.oid = a.attrelid
LEFT JOIN pg_index i ON
(pgc.oid = i.indrelid AND i.indkey[0] = a.attnum)
LEFT JOIN pg_description com on
(pgc.oid = com.objoid AND a.attnum = com.objsubid)
LEFT JOIN pg_attrdef def ON
(a.attrelid = def.adrelid AND a.attnum = def.adnum)
WHERE a.attnum > 0 AND pgc.oid = a.attrelid
AND pg_table_is_visible(pgc.oid)
AND NOT a.attisdropped
AND pgc.relname = 'TABLE_NAME' -- Your table name here
ORDER BY a.attnum;
返回结果如下:
num | name | typ | notnull | comment | primary_key
-----+-------------+-----------------------------+---------+---------------------+-------------
1 | id | integer | t | a primary key thing | t
2 | ref | text | f | | f
3 | created | timestamp without time zone | t | | f
4 | modified | timestamp without time zone | t | | f
5 | name | text | t | | f
num:列号
name:列名
类型:数据类型
notnull:列是否定义为NOT NULL
注释:为列定义的任何COMMENT
primary_key:列是否定义为PRIMARY KEY
default:用于默认值的命令
【讨论】:
哇哦!您真棒 !非常感谢! np :) .... 如果问题解决了您的问题,则将问题标记为已回答,以向其他人表明他们不需要回复。 对不起!如果我需要序列和默认属性?怎么能做到这一点?在同一个查询中......对不起,我不想虐待你! 您需要加入pg_attrdef
表... 更新示例
+1 这是一个很好的答案。但它有一些盲点。我添加了另一个答案。【参考方案2】:
基于answer by @Chris:
SELECT a.attnum
,a.attname AS name
,format_type(a.atttypid, a.atttypmod) AS typ
,a.attnotnull AS notnull
,coalesce(p.indisprimary, FALSE) AS primary_key
,f.adsrc AS default_val
,d.description AS col_comment
FROM pg_attribute a
LEFT JOIN pg_index p ON p.indrelid = a.attrelid AND a.attnum = ANY(p.indkey)
LEFT JOIN pg_description d ON d.objoid = a.attrelid AND d.objsubid = a.attnum
LEFT JOIN pg_attrdef f ON f.adrelid = a.attrelid AND f.adnum = a.attnum
WHERE a.attnum > 0
AND NOT a.attisdropped
AND a.attrelid = 'schema.tbl'::regclass -- table may be schema-qualified
ORDER BY a.attnum;
但是:
表名在数据库中不是唯一的,因此也不在系统目录中。您可能必须对名称进行模式限定。
使用a.attrelid = 'tbl'::regclass
作为条件。这样您就可以将myschema.mytbl
作为名称传递并消除歧义。那么在这种情况下根本不需要加入pg_class
。
此外,会自动检查 regclass
的可见性,不需要 pg_table_is_visible()
。
主键可以跨越多列。我通过在a.attnum = ANY(p.indkey)
上加入pg_index
来解决这个问题。indkey
的类型为int2vecor
,这是int2[]
的特例,仅在目录中使用。
我发现psql -E
有助于解决这类问题。
兼容性
这样的专门查询可能会在主要版本更新后中断。 Postgres 不保证目录表保持稳定。基本元素改变的可能性极小,但是查询越复杂和专业,机会就越大。您可以改用information schema,它是标准化的,但也相对较慢。
【讨论】:
非常感谢老兄! :D 你真棒! @user2266294:注意添加的关于兼容性的免责声明。【参考方案3】:我想你可以用这个:
select ordinal_position AS num, column_name as name, data_type as typ, character_maximum_length as lenth,
is_nullable as nullable, column_default as default
from INFORMATION_SCHEMA.COLUMNS
WHERE table_catalog='DatabaseName' AND table_name='TableName'
【讨论】:
以上是关于如何使用 PostgreSQL 从表名中获取列属性查询?的主要内容,如果未能解决你的问题,请参考以下文章
sql SQLSCRIPT HANA从表名中按字符串动态选择*