我正在寻找一种方法来运行查询以查找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
对于我的目的而言并不重要,并且根本不重要。
答案 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,但遇到了一些困难:
NOT a.attisdropped
资格。它不一致,我不得不遍历结果并检查列名称。'I am default'::character varying
当它们被填充到Web表单输入值时不起作用。我没有想到一个很好的方法来删除强制转换后缀而不执行像.replace(/::.*/, '')
那样不够强大的东西。我敢打赌,Erwin可以找到一些神奇的方式来EVAL()
返回的值,并使用a.atttypid
列来获得正确的数据类型。所以我回到了以前做的事情:
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