GORM对接SQL Server自增主键失效 事务内外报错不同如何解决
GORM对接SQL Server自增主键插入异常问题解答
事务内外报错不同的原因
核心根因是你数据库中MyStructures表的ID字段并未设置SQL Server专属的IDENTITY自增属性,两种场景报错差异来自GORM SQL Server驱动的执行逻辑区别:
- 事务内执行时:GORM默认假设标记了
autoIncrement:true的字段对应表字段自带IDENTITY自增属性,因此生成的INSERT语句不会携带ID字段,期望数据库自动生成值。但你的表ID字段无自增属性、也不允许为空,数据库无法自动填充值,因此抛出Cannot insert the value NULL into column 'ID'错误。 - 非事务直接执行时:GORM SQL Server驱动会额外做兼容处理,自动追加
SET IDENTITY_INSERT开关语句,尝试绕过自增校验强制插入后返回主键值。但你的表本身没有IDENTITY属性,数据库不允许执行该SET语句,因此抛出Table 'MyStructures' does not have the identity property错误。
自增主键正常生效的解决方案
根据你的业务需求二选一即可:
方案1:使用数据库层面的自增主键
- 先调整数据库表结构,给ID字段添加IDENTITY自增属性,执行SQL如下:
-- 如果ID已有主键约束,需要先删除原有约束再执行以下语句 ALTER TABLE MyStructures ALTER COLUMN ID INT IDENTITY(1,1) PRIMARY KEY;
- 原有结构体的GORM标签不需要修改,保持
gorm:"primaryKey;autoIncrement:true"即可。调整后事务内外执行Create操作都会正常,GORM生成的INSERT语句不带ID字段,数据库自动生成自增值并返回给结构体的ID字段。
方案2:代码层面自行生成主键值
如果不需要数据库自增,由业务代码生成唯一ID:
- 修改结构体的GORM标签,删除
autoIncrement:true配置:
type MyStructure struct { ID int32 `gorm:"primaryKey"` SomeFlag bool `gorm:"not null"` Name string `gorm:"type:varchar(60)"` }
- 插入数据时必须主动给ID字段赋值,保证值唯一即可,此时GORM不会生成IDENTITY相关的操作语句,事务内外都可以正常执行。
内容的提问来源于stack exchange,提问作者MLplck
相关产品推荐
相关产品推荐

