go-gorm / gorm

The fantastic ORM library for Golang, aims to be developer friendly
https://gorm.io
MIT License
36.95k stars 3.93k forks source link

mysql Pluck 无法使用decimal #5091

Closed liyuan1125 closed 2 years ago

liyuan1125 commented 2 years ago

GORM Playground Link

https://github.com/go-gorm/playground/pull/437

Description

wallet := UserWallet{UserID: 1, Balance: decimal.NewFromFloat(99.60)}

    if err := DB.Create(&wallet).Error; err != nil {
        t.Errorf("Failed, got error: %v", err)
    }

    var balance decimal.Decimal
    if err := DB.Model(&UserWallet{}).Limit(1).Pluck("balance", &balance).Error; err != nil {
        t.Errorf("Failed, got error: %v", err)
    }

    if err := DB.Model(&UserWallet{}).Limit(1).Pluck("balance", balance).Error; err != nil {
        t.Errorf("Failed, got error: %v", err)
    }

错误:

sql: Scan error on column index 0, name "balance": destination not a pointer
Heliner commented 2 years ago

check the https://gorm.io/docs/advanced_query.html , Pluck return mutilple values .

like this

var balance []decimal.Decimal
if err := DB.Model(&UserWallet{}).Limit(1).Pluck("balance", &balance).Error; err != nil {
t.Errorf("Failed, got error: %v", err)
}
liyuan1125 commented 2 years ago

check the https://gorm.io/docs/advanced_query.html , Pluck return mutilple values .

like this

var balance []decimal.Decimal
if err := DB.Model(&UserWallet{}).Limit(1).Pluck("balance", &balance).Error; err != nil {
t.Errorf("Failed, got error: %v", err)
}
var id uint64
if err := DB.Model(&UserWallet{}).Limit(1).Pluck("id", &id).Error; err != nil {
t.Errorf("Failed, got error: %v", err)
}
fmt.Print(id)

output

1
Heliner commented 2 years ago

this cause by Scan.scan() function args image this func set this db raw data into result or results, when the type is uint64 or uint32 ... that set this last query raw data into result, when the type is an arrry or slice .. that set this all query raw data into results

var id uint64
if err := DB.Model(&UserWallet{}).Limit(1).Pluck("id", &id).Error; err != nil {
   t.Errorf("Failed, got error: %v", err)
}
fmt.Print(id)

you can use Pluck like this but if limit (n=..), n is greater than 1, an unexpect result will return

    wallet := UserWallet{UserID: 1, Balance: decimal.NewFromFloat(99.60)}
    wallet2 := UserWallet{UserID: 2, Balance: decimal.NewFromFloat(100.60)}

    if err := DB.Create(&wallet).Error; err != nil {
        t.Errorf("Failed, got error: %v", err)
    }
    if err := DB.Create(&wallet2).Error; err != nil {
        t.Errorf("Failed, got error: %v", err)
    }

    var id2 uint64
    if err := DB.Model(&UserWallet{}).Limit(2).Pluck("id", &id2).Error; err != nil {
        t.Errorf("Failed, got error: %v", err)
    }
    fmt.Printf("id:%v", id2)

so, you can use Limit(1).Pluck("id", &id) ,I don't known that is a feature or bug , but that is a special case and doc not recommand use Pluck do like this

liyuan1125 commented 2 years ago

this cause by Scan.scan() function args image this func set this db raw data into result or results, when the type is uint64 or uint32 ... that set this last query raw data into result, when the type is an arrry or slice .. that set this all query raw data into results

var id uint64
if err := DB.Model(&UserWallet{}).Limit(1).Pluck("id", &id).Error; err != nil {
   t.Errorf("Failed, got error: %v", err)
}
fmt.Print(id)

you can use Pluck like this but if limit (n=..), n is greater than 1, an unexpect result will return

  wallet := UserWallet{UserID: 1, Balance: decimal.NewFromFloat(99.60)}
  wallet2 := UserWallet{UserID: 2, Balance: decimal.NewFromFloat(100.60)}

  if err := DB.Create(&wallet).Error; err != nil {
      t.Errorf("Failed, got error: %v", err)
  }
  if err := DB.Create(&wallet2).Error; err != nil {
      t.Errorf("Failed, got error: %v", err)
  }

  var id2 uint64
  if err := DB.Model(&UserWallet{}).Limit(2).Pluck("id", &id2).Error; err != nil {
      t.Errorf("Failed, got error: %v", err)
  }
  fmt.Printf("id:%v", id2)

so, you can use Limit(1).Pluck("id", &id) ,I don't known that is a feature or bug , but that is a special case and doc not recommand use Pluck do like this

I think its a bug https://github.com/go-gorm/gorm/issues/4457