Sql 获取Postgres中表列的默认值?
我正在寻找一种方法来运行查询,以查找Postgres中表列的默认值。例如,如果我使用以下查询创建了一个表: **编者按:我修复了表定义,因为它对问题没有影响 我需要一个查询,以某种格式告诉我,Sql 获取Postgres中表列的默认值?,sql,postgresql,default,Sql,Postgresql,Default,我正在寻找一种方法来运行查询,以查找Postgres中表列的默认值。例如,如果我使用以下查询创建了一个表: **编者按:我修复了表定义,因为它对问题没有影响 我需要一个查询,以某种格式告诉我,integer的默认值是2,text是“我是默认值”,而moretext是“我也是默认值”。查询结果可以包括没有默认值的任何其他列的任何值,即,不重要对我来说不重要,根本不重要 SELECT adsrc as default_value FROM pg_attrdef pad, pg_atttribut
integer
的默认值是2,text
是“我是默认值”,而moretext
是“我也是默认值”。查询结果可以包括没有默认值的任何其他列的任何值,即,不重要
对我来说不重要,根本不重要
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的查询。你可以试试这个来检查它是否有效。要获取所有列的值,可以尝试从where子句中删除和pat.attname='your\u column\u name'
。只需键入“\d table\u name”命令,它就会显示有关
表,例如列的默认值
--创建表格
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
是博士后真理的源泉:
SELECT pg_get_expr(d.adbin, d.adrelid) 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
只要列存在,就会保证结果。如果没有默认值,则会得到NULL
——这恰好是默认值。而且几乎总是正确的。但请看:
JOIN
,并准备偶尔不获取行
特殊类型转换::regclass
考虑搜索路径的当前设置。对于不符合模式限定的名称(当然,您应该这样做!),您可能会也可能不会得到预期的结果。见下面的反驳。相关的:
一旦我们有了表的OID,就不需要包括pg_类
。没有它,速度更快
为什么第一个答案不行
这几乎是正确的,但并不完全正确。有几个问题。我把它复制到这里以备将来参考请勿使用此项:
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\u attribute
中的打字错误-易于修复
- 如果没有为请求的列指定默认值,则不返回任何行。最好在..
上设置一个左连接pg_attrdef,这样,如果列存在,您总是会得到一个结果行。如果没有默认值,它将为NULL,这实际上是正确的结果,因为NULL
是默认值
如果从WHERE子句中删除attname
,则只能获取实际具有默认值的列的值。不适合其他人。您需要将attname
添加到选择列表中,否则您将不知道是哪一列
查询还将返回已删除的列的默认值,即错误。阅读关于这个问题的文章
最重要的是:查询可能会给出完全错误的结果,因为它没有考虑架构名称。postgres数据库中可以有任意数量的table1.col1
:在各种模式中。如果有多个默认值,则会得到多个值。如果您心目中的列没有默认值,但另一个模式中的另一个列有默认值,那么您将被愚弄,永远不会知道它
最后一点:在最新的PostgreSQL版本中,commit fe5038236c从pgêattrdef
中删除了adsrc
列,因为它在PostgreSQL中是多余的、不推荐使用的和未使用的
总而言之:一些没有洞察的博客的C/p出现了危险的错误。使用信息模式:
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数据库系统。我喜欢,但有一些困难:
有时我会得到列名“……pg.dropped.30……”等,即使有而不是a.attisdropped
限定。这是不一致的,我不得不循环检查结果并检查列名
返回的默认值有时会附加一个强制转换,例如,'I am default':character variabling
,当它们被填充到web表单输入值中时,该转换不起作用。如果不执行.replace(/::..*/,'')
之类的操作,我想不出删除强制转换后缀的好方法,因为这样做不够健壮。我打赌Erwin可以想出一些神奇的方法来获取返回值,并使用a.atttypid
列来获取正确的数据类型
所以我回到了我以前做的事情:
BEGIN;
INSERT INTO mytable DEFAULT VALUES RETURNING *;
ROLLBACK;
这里需要注意的一点是,任何SERIAL
列都将递增。如果它只是一个表索引,那么只要它是唯一的,这可能并不重要。否则它就是一个交易破坏者
另一件需要注意的事情是插入后/插入前的任何触发器,即使INSERT
回滚也会触发(我认为触发器函数所做的任何更改都会回滚)。我正在花一些时间尝试处理pg_目录表。我假设这些名字都是从那些需要单独雕刻字母的日子里回来的,因此非常昂贵;-)不管怎样,这都是生活中的事实。我想获得一列的默认值,并运行到这个线程中。我看到有人提到希望将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;
我使用的代码(可能是不人道的方式)如下:
从这里我想我会写一个观点,等等,一旦我更好地知道我真正想要的是什么。现在,我使用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_目录有了新的认识。他问我如何查询def
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)
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'