获取Postgres中表列的默认值?

时间:2011-11-16 03:49:12

标签: sql postgresql default

我正在寻找一种方法来运行查询以查找Postgres中表的列的默认值。例如,如果我使用以下查询创建表:

**编者注:我修改了表定义,因为它对问题没有影响。

CREATE TABLE mytable (
    integer int DEFAULT 2,
    text varchar(64) DEFAULT 'I am default',
    moretext varchar(64) DEFAULT 'I am also default',
    unimportant int 
);

我需要一个查询,告诉我,在某种格式中,integer的默认值为2,text为“我是默认值”,moretext为“我是也默认'。查询结果可以包含任何其他没有默认值的列的任何值,即unimportant对于我的目的而言并不重要,并且根本不重要。

6 个答案:

答案 0 :(得分:39)

使用信息架构:

SELECT column_name, column_default
FROM information_schema.columns
WHERE (table_schema, table_name) = ('public', 'mytable')
ORDER BY ordinal_position;

 column_name │             column_default             
─────────────┼────────────────────────────────────────
 integer     │ 2
 text        │ 'I am default'::character varying
 moretext    │ 'I am also default'::character varying
 unimportant │ 
(4 rows)

在架构命名之前,这应该适用于任何SQL数据库系统。

答案 1 :(得分:13)

@ Zohaib的查询几乎但不太正确。有几个问题。 我把它复制到我的答案中以供将来参考。 请勿使用

SELECT adsrc as default_value
 FROM pg_attrdef pad, pg_atttribute pat, pg_class pc
 WHERE pc.relname='your_table_name'
     AND pc.oid=pat.attrelid AND pat.attname='your_column_name'
     AND pat.attrelid=pad.adrelid AND pat.attnum=pad.adnum
  • 他从一些博客中复制过来。他提到这很好。但在这种情况下,应该添加源。阅读该博客的人需要收到警告。

  • pg_atttribute中的错字 - 很容易修复。

  • 如果没有为请求的列指定默认值,则不返回任何行。最好将其设为LEFT JOIN pg_attrdef ON ..,以便始终在列存在时获取结果行。它将为NULL,如果没有默认值,这实际上是正确的结果,因为NULL 是默认值。

  • 如果从WHERE子句中删除attname,则只获取实际具有默认值的列的值。不适合他人。您需要将attname添加到SELECT列表中,否则您将不知道哪一列。

  • 查询还会返回已删除的列的默认值,即错误。阅读details in the manual

  • 但最重要的是:查询可以提供完全错误的结果,因为它不会考虑架构名称。 postgres数据库中可以有任意数量的table1.col1:在各种模式中。如果多个具有默认值,则会获得多个值。如果您想到的列没有默认值,但另一个架构中的另一个没有默认值,那么您将被愚弄并且永远不会知道它。

总结一下:

从没有洞察力的某个博客复制/粘贴危险错误!
试试这个:

SELECT d.adsrc AS default_value
FROM   pg_catalog.pg_attribute a
LEFT   JOIN pg_catalog.pg_attrdef d ON (a.attrelid, a.attnum)
                                     = (d.adrelid,  d.adnum)
WHERE  NOT a.attisdropped   -- no dropped (dead) columns
AND    a.attnum > 0         -- no system columns
AND    a.attrelid = 'myschema.mytable'::regclass
AND    a.attname = 'mycolumn';

只要列存在,LEFT JOIN就会确保您获得结果。如果您要排除,请改为JOIN。但要做好准备偶尔不行。

请注意特殊广告::regclass会考虑search_path的当前设置,因此即使您没有在名称中包含架构(您应该确定!),你有机会获得预期的结果。 Read more about it in the manual

一旦我们拥有表的OID,包含pg_class就是多余的。跳过它并加快查询速度。

答案 2 :(得分:1)

我喜欢Erwin's Answer,但遇到了一些困难:

  1. 有时我会得到列名" ........ pg.dropped.30 ......."等,即使有NOT a.attisdropped资格。它不一致,我不得不遍历结果并检查列名称。
  2. 返回的默认值有时会附加一个强制转换,例如: 'I am default'::character varying当它们被填充到Web表单输入值时不起作用。我没有想到一个很好的方法来删除强制转换后缀而不执行像.replace(/::.*/, '')那样不够强大的东西。我敢打赌,Erwin可以找到一些神奇的方式来EVAL()返回的值,并使用a.atttypid列来获得正确的数据类型。
  3. 所以我回到了以前做的事情:

    BEGIN;
    INSERT INTO mytable DEFAULT VALUES RETURNING *;
    ROLLBACK;
    

    这里需要注意的是,任何SERIAL列都会增加。只要它只是一个表索引,它就没有关系。否则这是一个交易破坏者。

    要注意的另一件事是任何TRIGGER AFTER/BEFORE INSERT即使INSERT被回滚也会触发(我认为触发器功能所做的任何更改都会被回滚。)

答案 3 :(得分:0)

我花了一些时间试图掌握pg_catalog表。我假设这些名称是从必须单独雕刻字母的日子起回来的,因此价格非常昂贵;-)无论如何,这都是事实。我想获取列的默认值并遇到该线程。我看到有人提到想要将Erwin Brandstetter的代码作为函数使用。我把它包装好了,想把它添加到档案中:

CREATE OR REPLACE FUNCTION data.column_default (qualified_name text, column_name text)
  RETURNS text
 AS $$

SELECT d.adsrc AS default_value -- A human-readable representation of the default value, already typed as text.
FROM   pg_catalog.pg_attribute a
LEFT   JOIN pg_catalog.pg_attrdef d ON (a.attrelid, a.attnum)
                                     = (d.adrelid,  d.adnum)
WHERE  NOT a.attisdropped   -- no dropped (dead) columns
AND    a.attnum > 0         -- no system columns
AND    a.attrelid = qualified_name::regclass
AND    a.attname = column_name;

$$ LANGUAGE sql;

ALTER FUNCTION data.column_default (qualified_name text, column_name text) OWNER TO user_bender;

我正在使用这样的代码(可能以不人道的方式):

select pg_class.relnamespace::regnamespace as schema_name,
        attrelid::regclass as parent_name,
        attname,
       format_type(atttypid, atttypmod) as data_type,
       column_default(attrelid::regclass::text,attname),
       attnum

 from pg_attribute
 left join pg_class on (pg_class.oid = pg_attribute.attrelid::regclass)

从这里开始,我想我会写一个视图,等等,一旦我更好地了解了我真正想要的是什么。现在,我使用CTE作为临时视图:

with attributes as
(select pg_class.relnamespace::regnamespace as schema_name,
        attrelid::regclass as parent_name,
        attname,
       format_type(atttypid, atttypmod) as data_type,
       column_default(attrelid::regclass::text,attname),
       attnum

 from pg_attribute
 left join pg_class on (pg_class.oid = pg_attribute.attrelid::regclass)
)

select *
  from attributes
 where parent_name::text = 'sales'

所有的纠正,改进和建议都欢迎您...我只是在pg_catalog中弄湿了。

答案 4 :(得分:-1)

 SELECT adsrc as default_value
 FROM pg_attrdef pad, pg_atttribute pat, pg_class pc
 WHERE pc.relname='your_table_name'
     AND pc.oid=pat.attrelid AND pat.attname='your_column_name'
     AND pat.attrelid=pad.adrelid AND pat.attnum=pad.adnum

我在其中一个博客上找到了postgresql的查询。你可以尝试这个来检查它是否有效。要获取所有coumns的值,您可以尝试从where子句中删除AND pat.attname='your_column_name'

答案 5 :(得分:-2)

you can just type " \d table_name" command , then It will displays some information about the

表,例如列的默认值。

- 创建表格

skytf=> CREATE TABLE mytable (
skytf(>     a integer DEFAULT 2,
skytf(>     b varchar(64)  DEFAULT 'I am default',
skytf(>     c varchar(64)  DEFAULT 'I am also default'
skytf(> );
CREATE TABLE

- 显示表格信息

skytf=> \d mytable
                              Table "skytf.mytable"
 Column |         Type          |                   Modifiers                    
--------+-----------------------+------------------------------------------------
 a      | integer               | default 2
 b      | character varying(64) | default 'I am default'::character varying
 c      | character varying(64) | default 'I am also default'::character varying