Skip to content

not support LastInsertId() #24

Closed
Closed

Description

@astaxie

in the database/sql
the result has define

type Result

type Result interface {
    LastInsertId() (int64, error)
    RowsAffected() (int64, error)
}

but the pg drive don't support LastInsertId()

Activity

  1. bmizerany commented on Jun 12, 2012

    @bmizerany
    Contributor

    Correct. Postgres does not automatically return the last insert id, because it would be wrong to assume you're always using a sequence. You need to use the RETURNING keyword in your insert to get this information from postgres.

    Example:

    var id int
    err := db.QueryRow("INSERT INTO user (name) VALUES ('John') RETURNING id").Scan(&id)
    if err != nil {
    ...
    }
    

    More information here:
    http://www.postgresql.org/docs/8.2/static/sql-insert.html

  2. isaiah commented on Apr 1, 2013

    @isaiah

    Could you please kindly put this on the home page? Took me some time to find this piece of valuable information, someone from mysql may also get similar issue.

  3. bmizerany commented on Apr 2, 2013

    @bmizerany
    Contributor

    Maybe we should panic in that method?

    On Monday, April 1, 2013, Isaiah Peng wrote:

    Could you please kindly put this on the home page? Took me some time to
    find this piece of valuable information, someone from mysql may also get
    similar issue.

    —
    Reply to this email directly or view it on GitHubhttps://github.com//issues/24#issuecomment-15739654
    .

  4. kisielk commented on Apr 2, 2013

    @kisielk
    Contributor

    I think a panic with a message about using RETURNING would be appropriate, but I'm not sure how that would affect other libraries which may try to use database/sql in a driver-agnostic fashion. Might be worth asking bradfitz on golang-dev

  5. jackman0 commented on Apr 2, 2013

    @jackman0

    Quite personally, I thought the returned error message was clever. It
    didn't take me long to figure out that it wasn't supported. I am compelled
    to ask how OP is doing error handling?
    On Apr 1, 2013 10:27 PM, "Kamil Kisiel" notifications@github.com wrote:

    I think a panic with a message about using RETURNING would be appropriate,
    but I'm not sure how that would affect other libraries which may try to use
    database/sql in a driver-agnostic fashion. Might be worth asking bradfitz
    on golang-dev

    —
    Reply to this email directly or view it on GitHubhttps://github.com//issues/24#issuecomment-15752137
    .

  6. kisielk commented on Apr 2, 2013

    @kisielk
    Contributor

    hm yes, didn't realize it already returned an error. I agree that's enough, people should be checking those.

  7. added a commit that references this issue on Oct 29, 2015
  8. added a commit that references this issue on Apr 29, 2016
  9. paulm17 commented on Oct 23, 2016

    @paulm17

    How do I get the last ID from a prepared statement in a transaction?

    sql := `
        insert into [table] (col1, col2, col3, col4, col5, col6)
        values ($1, $2, $3, $4, $5, $6) RETURNING id;
    `
    stmt, err := db.Prepare(sql)
    
    if err != nil {
        panic(err)
    }
    
    res, err := stmt.Exec(data1, data2, data3, data4, data5, data6)
    
    if err != nil {
        panic(err)
    } else {
        ID, err = res.LastInsertId()
    
        if err != nil {
            panic(err)
        }
    }
    

    Of course I'm getting:
    panic: no LastInsertId available

    Everywhere I read, like above is to use QueryRow.

    Which I tried and works fine.

    What's the difference between Exec and QueryRow for this driver then?

  10. tamird commented on Oct 23, 2016

    @tamird
    Collaborator

    QueryRow returns a result, and Exec does not.

  11. cbandy commented on Oct 23, 2016

    @cbandy
    Contributor

    Maybe we should some more basics (or a link) to the docs?

  12. anacrolix commented on May 29, 2017

    @anacrolix

    According to the INSERT documentation, the default behaviour is to return the oid and count if no returning clause is present? https://www.postgresql.org/docs/9.6/static/sql-insert.html. If this is so, it should be made available to sql.Result.

  13. msakrejda commented on May 30, 2017

    @msakrejda
    Contributor

    Using OIDs is discouraged in user tables, and users will not insert directly into system tables. Do you have a use case for returning OIDs? It seems like the behavior you propose, while technically correct, would be confusing at best.

  14. anacrolix commented on May 31, 2017

    @anacrolix

    Yes, I want to update a row, sometime after I insert it. The use case is logging HTTP requests. I insert the initial values, and after responding, I update the row with stuff like response code, bytes written etc.

  15. msakrejda commented on May 31, 2017

    @msakrejda
    Contributor

    @anacrolix but are you using OIDs for those IDs? That's the only ids that Postgres returns to the client on insert, but they're not something you should be using--from the official docs:

    The use of OIDs in user tables is considered deprecated...

    The right way to solve this is to use the RETURNING clause and specify what data you would like to receive about the inserted row.

  16. added a commit that references this issue on Jul 25, 2017
  17. jwatte commented on May 8, 2018

    @jwatte

    You could update LastInsertId() to return the ID returned if the query has a RETURNING clause, else return -1 and an error. This would let people re-use code that uses LastInsertId() from other drivers, which is important from a compatibility point of view.

  18. Timmmm commented on Sep 29, 2018

    @Timmmm

    The error message for this is also not clear:

    no LastInsertId available
    

    That just sounds like I've done something wrong that means the driver couldn't get the last insert ID. It doesn't make it clear that it isn't supported at all.

  19. msakrejda commented on Sep 29, 2018

    @msakrejda
    Contributor

    @jwatte to do that pq would have to parse the query which introduces a ton of additional complexity and still doesn't handle cases like non-integer (e.g., uuid) identifiers.

    @Timmmm good point, but I think that message comes from https://github.com/golang/go/blob/50bd1c4d4eb4fac8ddeb5f063c099daccfb71b26/src/database/sql/driver/driver.go#L472 not pq. Maybe file an issue upstream?

  20. Timmmm commented on Oct 3, 2018

    @Timmmm

    @uhoh-itsmaciek Ah right you are - I opened a pull request.

  21. pdkovacs commented on May 16, 2021

    @pdkovacs

    @tamird
    As per specification, Exec should return a Result – unless an error occurs during execution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions