GORM 和 SQL Server:自动增量不起作用

Posted

技术标签:

【中文标题】GORM 和 SQL Server:自动增量不起作用【英文标题】:GORM and SQL Server: auto-incrementation does not work 【发布时间】:2021-10-13 18:50:50 【问题描述】:

我正在尝试使用 GORM 将新值插入到我的 SQL Server 表中。但是,它不断返回错误。您可以在下面找到详细示例:

type MyStructure struct 
    ID                     int32                    `gorm:"primaryKey;autoIncrement:true"`
    SomeFlag               bool                     `gorm:"not null"`
    Name                   string                   `gorm:"type:varchar(60)"`

执行下面的代码(使用 Create inside transaction)

myStruct := MyStructureSomeFlag: true, Name: "XYZ"

result = tx.Create(&myStruct)
    if result.Error != nil 
        return result.Error
    

导致以下错误:

无法将值 NULL 插入到列“ID”、表“dbo.MyStructures”中;列不允许空值。插入失败

GORM 生成的 SQL 查询如下所示:

INSERT INTO "MyStructures" ("SomeFlag","Name") OUTPUT INSERTED."ID" VALUES (1, 'XYZ')

另一方面,直接在 DB 连接上执行 Create(不使用事务)会导致以下错误:

表“MyStructures”没有标识属性。无法执行 SET 操作

GORM 生成的 SQL 查询如下所示:

SET IDENTITY_INSERT "MyStructures" ON;INSERT INTO "MyStructures" ("SomeFlag", "Name") OUTPUT INSERTED."ID" VALUES (1, 'XYZ');SET IDENTITY_INSERT "MyStructures" OFF;

在这种情况下如何使自动增量工作? 为什么我会收到两个不同的错误,这取决于它是内部交易还是外部交易?

【问题讨论】:

【参考方案1】:

我在 gorm 的问题中发现了这一点:

gorm.DefaultCallback.Create().Remove("mssql:set_identity_insert")

https://github.com/go-gorm/gorm/issues/941#issuecomment-250267125

【讨论】:

/****** 对象:表 [dbo].[MyStructures] 脚本日期:8/10/2021 10:13:07 AM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[MyStructures]( [ID] [bigint] IDENTITY(1,1) NOT NULL, [SomeFlag] [bit] NOT NULL, [Name] [varchar](60), PRIMARY KEY CLUSTERED ([ID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] 去 “当 IDENTITY_INSERT 设置为 ON 或复制用户插入 NOT FOR REPLICATION 标识列时,必须为表 'MyStructures' 中的标识列指定显式值”我没有更改任何内容在代码中。 你可以试试这个:***.com/questions/40178215/… 我在 gorm 问题中找到了这个:gorm.DefaultCallback.Create().Remove("mssql:set_identity_insert")github.com/go-gorm/gorm/issues/941#issuecomment-250267125【参考方案2】:

只需替换您的结构

type MyStructure struct 
    ID                     int32                    `gorm:"primaryKey;autoIncrement:true"`
    SomeFlag               bool                     `gorm:"not null"`
    Name                   string                   `gorm:"type:varchar(60)"`

有了这个

type MyStructure struct 
    ID                     int32                    `gorm:"AUTO_INCREMENT;PRIMARY_KEY;not null"`
    SomeFlag               bool                     `gorm:"not null"`
    Name                   string                   `gorm:"type:varchar(60)"`

【讨论】:

它不起作用。我仍然收到以下错误:mssql:表“MyStructures”没有标识属性。无法执行 SET 操作。【参考方案3】:

最好将 gorm.Model 嵌入到默认提供字段的结构中:ID、CreatedAt、UpdatedAt、DeletedAt。 ID默认为主键,自增(由GORM管理)

type MyStructure struct 
    gorm.Model
    SomeFlag               bool                     `gorm:"not null"`
    Name                   string                   `gorm:"type:varchar(60)"`

删除现有表:db.Migrator().DropTable(&MyStructure) 并再次创建表:db.AutoMigrate(&MyStructure),然后尝试插入记录。

【讨论】:

以上是关于GORM 和 SQL Server:自动增量不起作用的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 SQL Server Express Management Studio 设置自动增量?

SQL Server 将自动增量主键添加到现有表

在 Microsoft SQL Server 2008 R2 中重置自动增量

向 SQL server Compact 数据库插入自动增量密钥

GO使用sql server

Sql Server CE - 临时禁用特定列上的自动增量