postpresql 查询某张表的字段名和字段类型

postpresql 查询某张表的字段名和字段类型

工作中第一次接触postpresql,接触到这么个需求,只是对sql有点了解,于是就网上查阅资料。得知通过系统表可以查询,设计到几张系统表:pg_class、pg_attrubute、information_schema.columns 。

其中pg_class 这张表记录了所有表或者像表的东西。包括表、索引、视图、物化视图、组合类型和TOAST表。其中一些字段的含义如下表所示。

​ pg_class

字段名字段描述
oid表的唯一标识符(Object ID)
relname表的名称
relnamespace表所属的命名空间(pg_namespace 表的 oid)
reltype表的类型。对于表,这通常是 pg_type 表中的 oid
reloftype对于复合类型的表,它表示相关联的基础类型
relowner表的所有者(用户的 oid)
relam索引使用的存储方法的 oid
relfilenode表在磁盘上的文件节点号
reltablespace表所在的表空间的 oid
relpages表占用的页数
reltuples表中的元组数。
reltoastrelid如果存在,指向 pg_class 中的 TOAST 表的 oid
reltoastidxid如果存在,指向 TOAST 表的索引的 oid
relhasindex表是否有索引
relisshared表是否是共享的
relpersistence表的持久性(永久的还是临时的)
relkind表的类型,可能是 ‘r’(表)、‘i’(索引)等
relchecks表约束的数量
reltriggers表触发器的数量
relhasrules表是否有规则
relhasoids表是否有 OIDs(Object Identifiers)

pg_attrubute

这张表包含了有关表的每一列的详细信息,例如数据类型、是否为空等。

字段名字段描述
attrelid:属性所属的表的 OID。
attname:列名。
atttypid列的数据类型的 OID,对应于 pg_type 表中的 oid。
attstattarget用于统计信息的目标值。
attlen列的长度(以字节为单位)。
attnum列的序号。正整数表示用户定义的列,0 表示系统列。
attndims数组的维数,如果不是数组则为 0。
attcacheoff用于计算偏移量的缓存位置。
atttypmod类型修饰符。对于 varchar(n) 这样的类型,它存储 n 的值。
attbyval如果列的传递是按值传递,则为 true;否则为 false。
attstorage列的存储方式(‘p’ 表示普通、‘e’ 表示外部、‘m’ 表示主内存)。
attalign列的对齐方式(‘c’ 表示 CHAR、‘s’ 表示 SHORT、‘i’ 表示 INT、‘d’ 表示 DOUBLE)。
attnotnull如果列不允许为空,则为 true;否则为 false。
atthasdef如果列有默认值,则为 true;否则为 false。
attisdropped如果列已被删除,则为 true;否则为 false。
attislocal如果列是表的本地列,则为 true;否则为 false。
attinhcount列是否继承自父表。
attcollation列的排序规则的 OID。
attacl列的访问控制列表。
attoptions列的选项。
attfdwoptions表示列是否有存储外部化的选项。
attmissingval缺失值。

原本的想法,或者说是拿到的代码。要查的是adb_task_daily_detail_log 这张表的字段类型和数据

-- 取字段名和字段类型
select
a.attname as name,
format_type(a.atttypid,a.atttypmod) as type,
col_description(a.attrelid,a.attnum) as comment,
a.attnotnull as notnull
from
pg_class as c,
pg_attribute as a
where
c.relname='adb_task_daily_detail_log'
and
a.attrelid=c.oid -- 关联条件
and
a.attnum>0;

问题出现了,对于adb_task_daily_detail_log这张表,pg_class出现了2条记录。

查了半天也搞不懂为什么有两条记录,如果有大哥知道的话请指导下小弟。

有说多一条索引,就会多一条记录,但是这张表也没有索引。

有说表记录了TOAST相关的信息也会多存储一条relkind =‘t’ 的记录,但是这两条记录都是’r’。

所以后果就是查询出来的字段数量会重复。

方式2:

查information_schema.columns

information_schema.columns 是 PostgreSQL 中的系统视图之一,它存储了数据库中所有表的列信息。这个视图允许用户查询表的元数据,包括列名、数据类型、是否为主键、是否允许为空等。

字段名称字段描述
table_catalog表所属的数据库名称。
table_schema表所属的模式(Schema)名称。
table_name表的名称。
column_name列的名称。
ordinal_position列在表中的位置,从 1 开始。
column_default列的默认值。
is_nullable如果列允许为 NULL,则为 “YES”;否则为 “NO”。
data_type列的数据类型。
character_maximum_length如果数据类型是字符型,则是字符的最大长度。
character_octet_length字符的八位字节长度。
numeric_precision如果数据类型是数字型,则是精度。
numeric_precision_radix数字的基数(通常为 10)。
numeric_scale如果数据类型是数字型,则是小数点后的位数。
datetime_precision如果数据类型是日期时间型,则是小数秒的位数。
interval_type如果数据类型是间隔型,则是间隔类型。
interval_precision如果数据类型是间隔型,则是间隔的精度。
character_set_catalog字符集所属的数据库名称。
character_set_schema字符集所属的模式名称。
character_set_name字符集的名称。
collation_catalog校对规则所属的数据库名称。
collation_schem校对规则所属的模式名称。
collation_name校对规则的名称。
domain_catalog如果列是域类型的基础类型,则是基础类型所属的数据库名称。
domain_schema如果列是域类型的基础类型,则是基础类型所属的模式名称。
domain_name如果列是域类型的基础类型,则是基础类型的名称。
select 
	column_name
	concat(
  	data_type,
    case 
    	when character_maximum_length is not null then '(' || character_maximum_length || ')'
    	else ''
    end
  ) as type

from information_schema.columns
where table_name ='adb_task_daily_detail_log';

为了要使得数据类型和长度一起显示 做了一个拼接,但是只有字符类型的数据才会被拼接。需求是对数字类型的数字也拼接。

format_type 这个函数得到的数据就是满足要求的。

方式3:

select 
 attname as name
 format_type (atttypeid,atttypmod) as type
 from
 	pg_attribute
 where
 	attrelid ='adb_task_daily_detail_log'::regclass and 
 	attnum>0;
  • ::regclass 是 PostgreSQL 的类型转换语法。它将一个标识符(在这里是字符串 'adb_task_daily_detail_log')转换为 regclass 类型。
  • attrelidpg_attribute 表中的一个字段,表示属性(列)所属的表的 OID。

所以,attrelid = 'adb_task_daily_detail_log'::regclass 这个条件是在过滤 pg_attribute 表的记录,只选择属于名为 'adb_task_daily_detail_log' 的表的记录。

这样做是因为在 PostgreSQL 中,每个表都有一个唯一的 OID,而 pg_attribute 表存储了关于表的每个列的信息。通过检查 attrelid,我们可以限制结果只包括特定表的列信息。

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值