咨询PostgreSQL中自定义默认约束名称的存储位置
嘿,我完全懂你现在的困惑——从SQL Server转到PostgreSQL,习惯了能轻松查到带名字的默认约束,结果自己建了命名约束后,查pg_constraint和information_schema.columns却没找到想要的信息?别担心,这是因为PostgreSQL里查询默认约束的方式和SQL Server有点不一样,我来给你说清楚怎么找。
首先,你创建的那个命名默认约束绝对是存在的,只是你之前的查询没精准筛选。pg_catalog.pg_constraint确实是存储约束的核心视图,但你需要指定筛选默认约束的类型:
直接用pg_constraint查询命名默认约束
执行下面的SQL,就能精准定位到你给IsInterfaceView列设置的DF_EntitiesSQLObjectNamesMapping_IsInterfaceView约束:
SELECT conname AS constraint_name, conrelid::regclass AS table_name, pg_get_constraintdef(c.oid) AS constraint_definition FROM pg_catalog.pg_constraint c WHERE contype = 'd' -- 'd'代表默认约束类型 AND conrelid = 'public.EntitiesSQLObjectNamesMapping'::regclass;
这里的关键点是contype = 'd',它会过滤出所有默认约束;conrelid::regclass则是把表的OID转换成可读的表名,方便你确认所属表。
用information_schema关联查询
如果你习惯用information_schema的视图,那需要把table_constraints和constraint_column_usage关联起来,再结合pg_constraint拿到默认值的表达式:
SELECT tc.constraint_name, tc.table_schema, tc.table_name, ccu.column_name, pg_get_constraintdef(pc.oid) AS default_value_expression FROM information_schema.table_constraints tc JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name AND tc.table_schema = ccu.table_schema AND tc.table_name = ccu.table_name JOIN pg_catalog.pg_constraint pc ON tc.constraint_name = pc.conname WHERE tc.constraint_type = 'DEFAULT' AND tc.table_name = 'EntitiesSQLObjectNamesMapping' AND tc.table_schema = 'public';
为什么之前查information_schema.columns找不到约束名?因为这个视图里的column_default只存默认值的表达式,根本不存储约束的名称,所以得通过表约束的视图去关联查询。
补充小知识点
如果你创建列时没有显式给默认约束命名,PostgreSQL会自动生成一个类似tablename_colname_default的系统命名,但你显式指定的约束名会被完整保留,就像你例子里的DF_EntitiesSQLObjectNamesMapping_IsInterfaceView,用上面的查询肯定能查到它。
内容的提问来源于stack exchange,提问作者gotqn

