简体   繁体   中英

How to update several columns in PostgresQL table with a Go function

I use PostgresQL and Go. I have a table which is called users . I try to write a function which will be able to update several columns. This function takes column names and user object (type struct). Can you help me with this?

This is a User struct in Go:

type User struct {
  ID          int       json:"id"
  Username    string    json:"username"
  Password    string    json:"password"
  FirstName   string    json:"first_name"
  LastName    string    json:"last_name"
  Email       string    json:"email"
}

This is SQL script which creates users table:

create table "users"
(
  id                       serial       not null
  constraint user_pk
  primary key,
  username                 varchar(64)  not null,
  password                 varchar(128) not null,
  first_name               varchar(64)  not null,
  last_name                varchar(64)  not null,
  email                    varchar(64)  not null
);

1st example: I can pass first_name & last_name + full User object (postgres should update only these 2 fields)

2nd example: I can pass first_name & email & username + full User object (postgres should update only these 3 fields)

I have tried to do it with map but I could not:

func UpdateUser(db *sql.DB, m map[string]interface{}) (*User, error) {
  for key, value := range m {

  }

  err := db.QueryRow(UPDATE "users" SET ())
}

Use UPDATE In the example i assume you have written the function, which takes variables. Lets assume the variables are:

  • firstName
  • lastName

The SQL code is as follows:

UPDATE users
SET first_name = firstName, last_name= lastName
WHERE [condition] 

You may find that you need to write a class for this with an overloaded constructor so that it takes any number of variables that you want.

Or better still write a function for each of the rows:

UPDATE users
SET first_name = firstName
WHERE [condition] 

UPDATE users
SET last_name= lastName
WHERE [condition]

etc. It just means that the user will have to enter the items one at a time.

https://www.w3schools.com/sql/sql_update.asp

Here's my user update func:

I pass a User struct to the function and don't worry about which fields need to be updated, I just update them all. The caller is working with a User they got from a previous func that returned it from the DB (I'll show you the API handler if you want to see that).

After the update I call the Get function to get the freshly updated record from the DB and return the User struct. This is for certainty that the caller can see precisely what they just did.

// Update a User identified by id
func (u *UserModel) Update(user *models.User) (*models.User, error) {
    stmt := `UPDATE user SET
            first_name = ?,
            last_name = ?,
            email = ?,
            phone = ?,
            status_id = ?
        WHERE id = ?`

    var userStatus models.UserStatus
    userStatusID := userStatus.GetID(user.Status)

    _, err := u.DB.Exec(stmt, user.FirstName, user.LastName, user.Email, user.Phone, userStatusID, user.ID)
    if err != nil {
        if mysqlErr, ok := err.(*mysql.MySQLError); ok {
            if mysqlErr.Number == 1062 && strings.Contains(mysqlErr.Message, "uk_user_email") {
                return nil, models.ErrDuplicateEmail
            }
        }
        return nil, err
    }

    user, err = u.Get(int(user.ID))
    if err != nil {
        return nil, err
    }

    return user, nil
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM