Delphi 11+FireDAC+PostgreSQL:新增记录后无法获取ID问题咨询
问题解答
这个现象是符合FireDAC与PostgreSQL组合的默认行为的,和UniDAC+MySQL的处理逻辑存在差异,原因及解决方法如下:
原因分析
- PostgreSQL的自增主键(
SERIAL或IDENTITY类型),FireDAC默认不会在执行Post后自动回填新增的ID值——它需要显式配置来触发ID的获取逻辑。 - 而UniDAC针对MySQL做了默认适配:MySQL的
AUTO_INCREMENT主键在插入后,UniDAC会自动调用522132获取ID并回填到数据集字段,所以能直接拿到值。
解决方法
1. 在Insert语句中添加RETURNING子句(最直接可靠)
PostgreSQL支持RETURNING语法,执行插入时可以直接返回新增的主键值,FireDAC会自动将这个值填充到对应的字段中:
INSERT INTO your_table (column1, column2) VALUES (:col1, :col2) RETURNING id
配置好这条SQL后,调用Append、赋值、Post之后,AQ['id']就能正确获取到新增的ID。
2. 使用FDConnection.ExecSQLScalar直接获取ID
如果是通过执行SQL语句插入而非数据集操作,可以用这个方法直接拿到返回的主键:
var NewID: Integer; begin NewID := FDConnection.ExecSQLScalar('INSERT INTO your_table (column1) VALUES (:val) RETURNING id', ['test_val']); end;
3. 配置数据集的刷新参数
确保TFDQuery的以下参数配置正确,配合RETURNING子句使用:
- 将
UpdateOptions.RefreshMode设置为rmRow或rmAll,这样Post后会刷新当前行的数据。 - 确认主键字段的
ProviderFlags属性包含pfInKey,让FireDAC正确识别主键字段。
注意事项
- 无论使用
SERIAL还是PostgreSQL 10+推荐的IDENTITY类型主键,RETURNING子句的方式都适用。 - PostgreSQL没有MySQL全局的
522132,它的currval()需要指定对应序列名且仅在当前会话有效,所以显式使用RETURNING是最通用的方案。
内容的提问来源于stack exchange,提问作者Stepel
相关产品推荐
相关产品推荐

