postgresqlgonullgrails-ormcoalesce

SQL COALESCE function is not working with GORM


DB.Model(&domain.Products{}).Where("product_code", product.Product_Code).
Updates(map\[string\]interface{}{
"product_image": gorm.Expr("COALESCE(?, products.product_image)", product.Product_Image),
"size":          gorm.Expr("COALESCE(?, products.size)", product.Size),
"color":         gorm.Expr("COALESCE(?, products.color)", product.Color),
"unit_price":    gorm.Expr("COALESCE(?, products.unit_price)", product.Unit_Price),
"stock":         gorm.Expr("COALESCE(?, products.stock)", product.Stock),
})

It is a gorm query to manage null value insertion when we updating a table. I want to update the table by keeping existing values there in the table if new value(incoming value) is null. But here in my code the table updating as normal which means , both null values and not null values are updating as usual. I hope anyone can help me

I tried gorm raw query also. But it also not working

ar.DB.Exec("UPDATE products SET size = COALESCE(?, size) WHERE product_code = ?", product.Size, product.Product_Code)

Solution

  • COALESCE returns the first argument that is not nil.

    For this to work you need to supply pointers. However, as one can see from the code snippet in your comment, no pointers are supplied. Therefore, all specified fields will be updated.

    Specifically, your Products (or whatever it is called in your program) type should look more like this:

    package domain
    
    type Products struct {
        Product_Code  int `gorm:"not null"`
        Product_Image *string
        Size          *int
        Color         *string
        Unit_price    *float64
        Stock         *int
    }
    

    Note that fields are defined as pointers.

    It would then be used like this:

    newStock := 12
    prod := domain.Products{    
        product_code: 42,   
        product_image: nil,     
        size: nil,  
        color: nil,     
        unit_price: nil,    
        stock: &newStock, 
    }
    

    Sine all fields are nil with the exception of stock only stock will be updated in the database.