英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论