MS Access前端/PostgreSQL后端:链接表主键生成随机失效求助
PostgreSQL与MS Access链接表主键重复问题
我使用PostgreSQL 10作为后端数据库,用户通过psql ODBC驱动连接MS Access 2007前端录入数据。目前遇到链接表的异常问题:
该表的transaction_id是主键,通过GENERATED ALWAYS AS IDENTITY自动生成递增编号。正常情况下,Access中留空该字段插入数据时,PostgreSQL会自动分配新编号,但频繁且随机地,插入新数据时transaction_id会重复使用表中已有的旧值,示例如下:
| transaction_id (PK) | date |
|---|---|
| 1 | 14-11-2022 |
| 2 | 14-11-2022 |
| 3 | 14-11-2022 |
| 4 | 14-11-2022 |
| 3 | 14-11-2022 |
| 3 | 14-11-2022 |
刷新链接表后,显示的transaction_id会恢复正常(旧的重复值会被更正为正确的递增编号),但立即插入新数据时,仍会使用同一个旧值作为主键:
| transaction_id (PK) | date |
|---|---|
| 1 | 14-11-2022 |
| 2 | 14-11-2022 |
| 3 | 14-11-2022 |
| 4 | 14-11-2022 |
| 5 | 14-11-2022 |
| 6 | 14-11-2022 |
| 7 | 14-11-2022 |
| 8 | 14-11-2022 |
| 3 (立即插入的新数据) | 14-11-2022 |
| 3 (立即插入的新数据) | 14-11-2022 |
必须等待一段时间后,主键才会恢复正常递增。但如果修改date字段的值,新插入数据的transaction_id会显示正确的编号:
| transaction_id (PK) | date |
|---|---|
| ... | ... |
| 3 | 14-11-2022 |
| 3 | 14-11-2022 |
| 11 | 10-11-2022 |
| 12 | 12-11-2022 |
| 3 | 14-11-2022 |
| 14 | 01-02-2022 |
由于有子窗体依赖transaction_id作为外键,主键重复会导致子窗体关联错误,数据紊乱。
已尝试的无效操作:
- 刷新Access链接表
- 关闭并重新打开表
- 将刷新间隔从60秒改为30秒
- 把原序列替换为
GENERATED ALWAYS AS IDENTITY列
表定义如下:
CREATE TABLE transactionlist ( transaction_id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY, transaction_date date, description VARCHAR(255), source VARCHAR(50), input_user int, input_date date);
解决建议
- 更新ODBC驱动:确保使用适配PostgreSQL 10和Access 2007的最新稳定版psql ODBC驱动,旧驱动可能存在身份列缓存或主键生成的兼容性问题。
- 调整链接表属性:
- 打开链接表设计视图,确认
transaction_id字段的"自动递增"属性设为"是","新值"设为"递增"; - 将链接表的"记录锁定"属性设为"编辑记录时锁定",避免多用户并发插入时的缓存冲突。
- 打开链接表设计视图,确认
- 禁用Access本地缓存:依次点击
文件>选项>客户端设置,取消勾选"缓存Web和SharePoint列表",强制Access每次插入时直接请求PostgreSQL生成主键,而非使用本地缓存值。 - 使用传递查询插入:创建Access传递查询,直接调用PostgreSQL插入语句,绕过Access的自动主键生成逻辑,完全由PostgreSQL控制编号生成,示例语句:
INSERT INTO transactionlist (transaction_date, description, source, input_user, input_date) VALUES (?, ?, ?, ?, ?) - 修改PostgreSQL身份列缓存:在
postgresql.conf中设置identity_cache = 1(关闭批量缓存),重启服务后可避免因缓存不同步导致的主键重复。 - 调整事务隔离级别:在ODBC连接属性中添加
Transaction Isolation Level=Read Committed,确保每次插入后事务及时提交,主键值同步到Access前端。
内容的提问来源于stack exchange,提问作者ag97
相关产品推荐
相关产品推荐

