pq: No way to see an Insert error from QueryRow()

I want to make an insert into a table with constraints. I also want to get the inserted id value if successful. The problem is if QueryRow() with an INSERT…RETURNING fails, then the error is a rather unhelpful no rows in result set.

The error I want would be something like: duplicate key violates unique constraint "user_email_unique" which is the error that’s returned by Exec() but then I don’t get the last inserted id if everything goes well.

About this issue

  • Original URL
  • State: closed
  • Created 11 years ago
  • Comments: 27 (14 by maintainers)

Commits related to this issue

Most upvoted comments

Just for the record, here’s some code from @chris-baynes to make this a little bit more comfortable, reproduced here incase the Gist disappears:

// similar to sql.Row but without the error field
type DbRowFromInsert struct {
    rows *sql.Rows
}

// Using sql.Row.Scan() as a template for this method, but modifying the errors.
func (row *DbRowFromInsert) Scan(dest ...interface{}) error {
    defer row.rows.Close()
    row.rows.Next()

    // There may be no rows, but Scan anyway to get the errors...
    // If there are no rows because of a db constraint error this is when those errors will be returned.
    err := row.rows.Scan(dest...)
    if err != nil {
        return err
    }

    return nil
}

// Usage:
func InsertReturning(query string, args ...interface{}) (*DbRowFromInsert, error) {
    rows, err := dbConn.Query(query, args...)
    if err != nil {
        return nil, err
    }

    return &DbRowFromInsert{rows: rows}, nil
}