GORM和SQL Server:自增功能无法正常工作。

huangapple go评论108阅读模式
英文:

GORM and SQL Server: auto-incrementation does not work

问题

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

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

执行以下代码(在事务内部使用Create):

myStruct := MyStructure{SomeFlag: 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;

在这种情况下,我该如何使自动递增功能正常工作?
为什么在事务内外会得到两个不同的错误?

英文:

I am trying to insert new value into my SQL Server table using GORM. However, it keeps returning errors. Below you can find detailed example:

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

Executing the code below (with Create inside transaction)

myStruct := MyStructure{SomeFlag: true, Name: "XYZ"}

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

results in the following error:

> Cannot insert the value NULL into column 'ID', table 'dbo.MyStructures'; column does not allow nulls. INSERT fails

SQL query generated by GORM looks then as follows:

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

On the other hand, executing Create directly on DB connection (without using transaction) results in the following error:

> Table 'MyStructures' does not have the identity property. Cannot perform SET operation

SQL query generated by GORM looks then as follows:

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

How can I make the auto-incrementation work in this case?
Why do I get two different errors depending on whether it is inside or outside transaction?

答案1

得分: 1

我在gorm的问题中找到了这个:

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

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

英文:

I find this in gorm's issues:

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

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

答案2

得分: 0

只需将您的结构体替换为以下内容:

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

Just replace your Struct

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

with this

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

答案3

得分: 0

在结构体中嵌入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{}),然后尝试插入记录。

英文:

It's always better to embed the gorm.Model in the struct which gives the fields by default: ID, CreatedAt, UpdatedAt, DeletedAt. ID will be the primary key by default, and it is auto-incremented (managed by GORM)

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

Drop the existing table: db.Migrator().DropTable(&MyStructure{}) and create the table again: db.AutoMigrate(&MyStructure{}) and then try to insert the record.

huangapple
  • 本文由 发表于 2021年8月10日 15:47:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/68722871.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定