Go: How to get last insert id on Postgresql with NamedExec()

huangapple go评论141阅读模式
英文:

Go: How to get last insert id on Postgresql with NamedExec()

问题

我在我的Go应用程序中使用jmoiron/sqlx库与我的PostgreSQL服务器进行通信。在我的应用程序的某个地方,我有以下代码:

sqlQuery := `
    INSERT INTO table_to_insert  (
        code,
        status,
        create_time,
        create_by
    ) VALUES (
        '',
        0,
        CURRENT_TIMESTAMP,
        0
    ) RETURNING id
`

datas, err := tx.NamedExec(sqlQuery, structToInsert)

问题:如何使用tx.NamedExec()的返回结果获取最后插入的id?我尝试过datas.LastInsertId(),但它总是返回0。

注意:我确定插入到PostgreSQL成功了。

英文:

I use jmoiron/sqlx library for communicating with my PostgreSql server in my Go apps. Somewhere on my apps i have this following code:

sqlQuery := `
    INSERT INTO table_to_insert  (
        code,
        status,
        create_time,
        create_by
    ) VALUES (
        '',
        0,
        CURRENT_TIMESTAMP,
        0
    ) RETURNING id
`

datas, err := tx.NamedExec(sqlQuery, structToInsert)

1: https://github.com/jmoiron/sqlx "jmoiron/sqlx"

Question: how can i get the last insert id using the return from tx.NamedExec()? I've tried datas.LastInsertId() but its always return 0.

Note: im sure the insert to postgres is success.

答案1

得分: 71

这是因为PostgreSQL不会返回最后插入的ID。这是因为只有在创建使用序列的表的新行时,最后插入的ID才可用。

如果你实际上在分配了序列的表中插入一行,你需要使用RETURNING子句。类似这样:INSERT INTO table (name) VALUES("val") RETURNING id

我不确定你使用的驱动程序,但在pq中,你可以这样做:

lastInsertId := 0
err = db.QueryRow("INSERT INTO brands (name) VALUES($1) RETURNING id", name).Scan(&lastInsertId)
英文:

The reason for this is because PostgreSQL does not return you the last inserted id. This is because last inserted id is available only if you create a new row in a table that uses a sequence.

If you actually insert a row in the table where a sequence is assigned, you have to use RETURNING clause. Something like this: INSERT INTO table (name) VALUES("val") RETURNING id".

I am not sure about your driver, but in pq you will do this in the following way:

lastInsertId := 0
err = db.QueryRow("INSERT INTO brands (name) VALUES($1) RETURNING id", name).Scan(&lastInsertId)

答案2

得分: 7

resp.LastInsertID()只适用于mySQL,并且仅适用于整数类型的ID:https://golang.org/pkg/database/sql/#Result

请注意,由于您正在使用sqlx(通过使用NamedExec),您应该改用tx.Get来执行查询并捕获返回值:

// id应该与您的ID类型匹配
// 例如,对于bigserial列,id应为int64,对于uuid,id应为string
var id string
resp, err := tx.Get(&id, query, v1, v2, v3)

请参阅sqlx GitHub存储库上的相关讨论:https://github.com/jmoiron/sqlx/issues/154#issuecomment-148216948

英文:

resp.LastInsertID() only (typically) works with mySQL, and only works for integer IDs: https://golang.org/pkg/database/sql/#Result

Note that since you're using sqlx (by the use of NamedExec) you'll want to instead use tx.Get to exec the query and capture the return value:

// id should match the type of your ID 
// e.g. int64 for a bigserial column, or string for a uuid
var id string
resp, err := tx.Get(&id, query, v1, v2, v3)

See this relevant discussion on the sqlx GitHub repo: https://github.com/jmoiron/sqlx/issues/154#issuecomment-148216948

huangapple
  • 本文由 发表于 2015年10月28日 12:35:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/33382981.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定