英文:
Go: panic error after creating a new record with tx.MustExec
问题
当我使用db.Exec
时,它能正常工作并创建记录,但会引发 panic 错误。我不知道为什么会这样。
我是一个 Go 语言的初学者,对这个错误的含义和如何解决不太确定。如果我注释掉 panic 部分,整个应用程序就能正常工作。
tx := db.MustBegin()
// _,err := db.Exec(queries.QueryInsertUserData, user.ID, user.Username, user.FirstName, user.LastName, user.Phone)
err := tx.MustExec("INSERT INTO users (id, created_at, updated_at, deleted_at, username, password, first_name, last_name, phone, status) VALUES($1, now(), now(), NULL, $2, NULL, $3, $4, $5, true)", user.ID, user.Username, user.FirstName, user.LastName, user.Phone)
tx.Commit()
if err != nil {
panic(err) // 引发错误
}
错误信息:
2022/05/28 09:57:17 http: panic serving [::1]:53468: {0xc0001b6000 1}
goroutine 35 [running]:
net/http.(*conn).serve.func1(0xc0001b2280)
/usr/local/go/src/net/http/server.go:1772 +0x139
panic(0x13538e0, 0xc0000a8780)
/usr/local/go/src/runtime/panic.go:975 +0x3e3
GO_APP/app/handler.CreateUser(0xc00009aea0, 0x13ff7c0, 0xc00018e1c0, 0xc0001d0000)
/Users/kritisahu/Desktop/go_app/app/handler/users.go:61 +0x7ec
GO_APP/app.(*App).CreateUser(...)
/Users/kritisahu/Desktop/go_app/app/app.go:47
github.com/julienschmidt/httprouter.(*Router).ServeHTTP(0xc000182420, 0x13ff7c0, 0xc00018e1c0, 0xc0001d0000)
/Users/kritisahu/go/pkg/mod/github.com/julienschmidt/httprouter@v1.3.0/router.go:387 +0xc37
net/http.serverHandler.ServeHTTP(0xc00018e0e0, 0x13ff7c0, 0xc00018e1c0, 0xc0001d0000)
/usr/local/go/src/net/http/server.go:2807 +0xa3
net/http.(*conn).serve(0xc0001b2280, 0x14000c0, 0xc0001ba040)
/usr/local/go/src/net/http/server.go:1895 +0x86c
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2933 +0x35c
请注意,我只提供了翻译的部分,不包括你要求的其他内容。
英文:
When I am using db.Exec
it's working fine and creating record as well but it's giving panic. I don't know why.
I am a beginner in golang so I am not sure what this error means and how to solve. My whole application works if I comment out panic part.
tx := db.MustBegin()
// _,err := db.Exec(queries.QueryInsertUserData, user.ID, user.Username, user.FirstName, user.LastName, user.Phone)
err := tx.MustExec("INSERT INTO users (id, created_at, updated_at, deleted_at, username, password, first_name, last_name, phone, status) VALUES($1, now(), now(), NULL, $2, NULL, $3, $4, $5, true)", user.ID, user.Username, user.FirstName, user.LastName, user.Phone)
tx.Commit()
if err != nil {
panic(err) // Giving error
}
Error:
2022/05/28 09:57:17 http: panic serving [::1]:53468: {0xc0001b6000 1}
goroutine 35 [running]:
net/http.(*conn).serve.func1(0xc0001b2280)
/usr/local/go/src/net/http/server.go:1772 +0x139
panic(0x13538e0, 0xc0000a8780)
/usr/local/go/src/runtime/panic.go:975 +0x3e3
GO_APP/app/handler.CreateUser(0xc00009aea0, 0x13ff7c0, 0xc00018e1c0, 0xc0001d0000)
/Users/kritisahu/Desktop/go_app/app/handler/users.go:61 +0x7ec
GO_APP/app.(*App).CreateUser(...)
/Users/kritisahu/Desktop/go_app/app/app.go:47
github.com/julienschmidt/httprouter.(*Router).ServeHTTP(0xc000182420, 0x13ff7c0, 0xc00018e1c0, 0xc0001d0000)
/Users/kritisahu/go/pkg/mod/github.com/julienschmidt/httprouter@v1.3.0/router.go:387 +0xc37
net/http.serverHandler.ServeHTTP(0xc00018e0e0, 0x13ff7c0, 0xc00018e1c0, 0xc0001d0000)
/usr/local/go/src/net/http/server.go:2807 +0xa3
net/http.(*conn).serve(0xc0001b2280, 0x14000c0, 0xc0001ba040)
/usr/local/go/src/net/http/server.go:1895 +0x86c
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2933 +0x35c
答案1
得分: 1
你之所以遇到错误,是因为Tx.MustExec方法不返回错误,而是返回一个接口类型。
type Result interface {
// LastInsertId返回数据库对命令的响应中生成的整数。
// 通常,这将来自插入新行时的“自增”列。
// 并非所有数据库都支持此功能,并且此类语句的语法也有所不同。
LastInsertId() (int64, error)
// RowsAffected返回受更新、插入或删除影响的行数。
// 并非每个数据库或数据库驱动程序都支持此功能。
RowsAffected() (int64, error)
}
因此,在你的代码中,err存储的是Result接口的值。你可以像这样修改代码:
result := tx.MustExec("INSERT INTO users (id, created_at, updated_at, deleted_at, username, password, first_name, last_name, phone, status) VALUES($1, now(), now(), NULL, $2, NULL, $3, $4, $5, true)", user.ID, user.Username, user.FirstName, user.LastName, user.Phone)
fmt.Println(result.RowsAffected())
英文:
You getting an error because Tx.MustExec does not return an error but it is returning an interface
type Result interface {
// LastInsertId returns the integer generated by the database
// in response to a command. Typically this will be from an
// "auto increment" column when inserting a new row. Not all
// databases support this feature, and the syntax of such
// statements varies.
LastInsertId() (int64, error)
// RowsAffected returns the number of rows affected by an
// update, insert, or delete. Not every database or database
// driver may support this.
RowsAffected() (int64, error)
}
so in your code err stores Result interface value. instead of err write like this
result := tx.MustExec("INSERT INTO users (id, created_at, updated_at, deleted_at, username, password, first_name, last_name, phone, status) VALUES($1, now(), now(), NULL, $2, NULL, $3, $4, $5, true)", user.ID, user.Username, user.FirstName, user.LastName, user.Phone)
fmt.Println(result.RowsAffected())
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论