【问题标题】:How to update several columns in PostgresQL table with a Go function如何使用 Go 函数更新 PostgresQL 表中的多个列
【发布时间】:2019-08-27 11:43:49
【问题描述】:

我使用 PostgresQL 和 Go。我有一张名为users 的表。我尝试编写一个能够更新几列的函数。此函数采用列名和用户对象(类型结构)。你能帮我解决这个问题吗?

这是 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"
}

这是创建用户表的 SQL 脚本:

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
);

第一个例子:我可以传递first_name & last_name + 完整的用户对象(postgres 应该只更新这两个字段)

第二个例子:我可以通过 first_name & email & username + 完整的用户对象(postgres 应该只更新这 3 个字段)

我试过用地图来做,但我做不到:

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

  }

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

【问题讨论】:

  • 您能展示一下到目前为止您已经尝试过什么以及遇到了什么问题吗?
  • @Adrian,问题已更新
  • 问题是我不知道postgres应该更新什么和多少字段
  • 如果您收到要更新的字段列表,那么您确实知道要更新的字段和数量,对吧?

标签: sql postgresql go


【解决方案1】:

使用更新 在示例中,我假设您已经编写了接受变量的函数。让我们假设变量是:

  • 名字
  • 姓氏

SQL代码如下:

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

你可能会发现你需要用一个重载的构造函数为此编写一个类,以便它接受你想要的任意数量的变量。

或者最好还是为每一行编写一个函数:

UPDATE users
SET first_name = firstName
WHERE [condition] 

UPDATE users
SET last_name= lastName
WHERE [condition]

等等。这只是意味着用户必须一次输入一个项目。

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

【讨论】:

  • 如果为一个字段写一个函数,将会对数据库进行大量查询
  • “用重载的构造函数为此编写一个类”什么? Go 没有类、重载和构造函数。
【解决方案2】:

这是我的用户更新函数:

我将一个 User 结构体传递给函数,不用担心需要更新哪些字段,我只是将它们全部更新。调用者正在使用他们从以前的函数中获得的用户,该函数从数据库返回它(如果你想看到,我将向你展示 API 处理程序)。

更新后我调用Get 函数从数据库中获取最新更新的记录并返回用户结构。这是肯定的,调用者可以准确地看到他们刚刚做了什么。

// 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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 2017-09-06
    • 2021-01-08
    • 1970-01-01
    相关资源
    最近更新 更多