最近我看到了PostgreSQL DB的奇怪场景。我的数据库的信息模式显示的序列名称与为表格列实际分配的序列名称不同。
问题是:
我有一个表tab_1
id name
1 emp1
2 emp2
3 emp3
以前表的id
列(integer
)是一个自动生成的字段,其中序列号是在运行时通过JPA生成的。 (序列名称:tab_1_seq
)
我们进行了更改并将表格的列id
更新为bigserial
,并且序列保持在列级别(分配的新序列:tab_1_temp_seq
)中,不再由JPA处理。
在这个改变之后,一切都运行良好几个月,之后我们遇到了一个错误 - “序列”tab_1_temp_seq“尚未在此会话中定义”
在分析问题时,我发现为表分配的序列之间存在不匹配。
在表格结构中,我们将序列显示为tab_1_temp_seq
,而在information_schema
中,表格分配了旧序列 - tab_1_seq
。
我不确定究竟是什么导致了这种情况发生,因为我们没有管理我们的数据库系统。如果你遇到过这样的问题,请告诉我它的根本原因。
查询:
从table_schema.columns中选择table table_name,column_name,column_default,其中table_name ='tab_1';
结果:
table_name column_name column_default
tab_1 id nextval('tab_1_seq::regclass')
以下是表结构/属性中的详细信息:
id nextval('tab_1_temp_seq::regclass')
name varChar
也许您正在遭受数据损坏,但您很可能会遇到可视化数据库对象的不良工具。无论程序向您显示“表结构/属性”可能会混淆。
要找出真相(DEFAULT
值PostgreSQL使用),运行:
SELECT pg_get_expr(adbin, adrelid)
FROM pg_attrdef
WHERE adrelid = 'tab1'::regclass;
这也是information_schema.columns
将展示的内容,但为了清晰起见,我添加了裸查询。
只要DEFAULT
语句未指定INSERT
列或使用特殊值id
填充它,就会使用此DEFAULT
值。
也许混淆也是由可能以其方式设置默认值的不同程序引起的。我上面展示的方式是PostgreSQL的方式,但没有什么能阻止第三方工具使用自己的序列来填充id
。