【问题标题】:How to get column attributes query from table name using PostgreSQL?如何使用 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'

但是,我需要评论!

【问题讨论】:

    标签: sql postgresql database-design attributes


    【解决方案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'
    

    【讨论】:

      猜你喜欢
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多