获取Postgres中表列的默认值?

sjc*_*hen 22 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 
);
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*aut 43

使用信息架构:

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)
Run Code Online (Sandbox Code Playgroud)

直到架构命名,这应该适用于任何SQL数据库系统.

  • "*在任何SQL数据库*中除了Oracle,因为他们仍然拒绝实现ANSI information_schema ... (8认同)

Erw*_*ter 15

@ 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
Run Code Online (Sandbox Code Playgroud)
  • 他复制了一些博客.他提到这很好.但在这种情况下,应该添加源.阅读该博客的人需要收到警告.

  • Typo in pg_atttribute- 很容易修复.

  • 如果没有为请求的列指定默认值,则不返回任何行.最好使它成为a LEFT JOIN pg_attrdef ON ..,所以如果列存在,你总是得到一个结果行.如果没有默认值,它将为NULL,这实际上是正确的结果,因为NULL 是默认值.

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

  • 该查询还将返回已删除的列的默认值,这是错误的.阅读手册中详细信息.

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

把它们加起来:

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

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';
Run Code Online (Sandbox Code Playgroud)

LEFT JOIN只要列存在,就确保获得结果.如果您想要排除这些,请JOIN改为使用它.但要做好准备偶尔不行.

请注意,特殊演员::regclass会考虑当前设置search_path,因此即使您没有在名称中包含架构(您应该确定!),您可能会得到预期的结果. 在手册中阅读更多相关信息.

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


Zoh*_*aib -2

 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
Run Code Online (Sandbox Code Playgroud)

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