1

To simplify the code, and prevent from passing similar arguments again and again, I created a method Put for some structures as below.
For example, the reason why UID is not used here is because UID was set as an auto increase value.

type User struct {
    UID      int
    Name     string
    Username string
    Password string
}

func (user *User) Put(db *sql.DB, query string) (sql.Result, error) {
    return db.Exec(query, u.UID, u.Name, u.Username, u.Password)
}

func main() {
    db := ...
    u := &User{...}

    u.Put(db, `INSERT INTO user(name, username, password) VALUES ($2, $3, $4);`)
}

But I get the error below

pq: could not determine data type of parameter $1

(SQL driver is https://github.com/lib/pq)

kozmo
  • 4,024
  • 3
  • 30
  • 48
  • 1
    Why does the query parameters start at `$2`? – kozmo Feb 11 '21 at 03:31
  • cause method `Put` puts `UID` which is not used in this query, but may be used in other queries. – Richard Chen Feb 11 '21 at 03:37
  • 1
    Don't separate the query string from its arguments; they belong together and should be treated as a unit. This will keep causing problems like this. In this particular case, why can't you move the query string directly into the Put method? Why does the caller have to supply it? What "other queries" would you ever call this with? – Peter Feb 11 '21 at 11:00

1 Answers1

0

In your query $2, $3...$N is the index of the argument that is passed in as extra arguments to db.Exec() and they must start from $1(if you use database/sql package).

I think in your case you may to change Put method signature (add struct values extractor)

func (user *User) Put(db *sql.DB, query string, extractor func(user User)[]interface{}) (sql.Result, error) {
    return db.Exec(query, extractor(*user)...)
}

and use one like

u.Put(db,`INSERT INTO user(name, username, password) VALUES ($1, $2, $3);`, func(u User) []interface{} {
    return []interface{}{u.Name, u.Username, u.Password}
})
kozmo
  • 4,024
  • 3
  • 30
  • 48