Go: how to retrieve multiple results from mysql with sql/db package

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

Go: how to retrieve multiple results from mysql with sql/db package

问题

我正在尝试使用Go语言中的sql/db包从表中获取数据。我的数据库表中包含一个用户名为"shaw"的用户。该用户名在post列中有几行不同的帖子。我有以下代码:

GO:

  1. func ReadData() string {
  2. db, err := sql.Open("mysql", "user1@/my_db")
  3. if err != nil {
  4. fmt.Println(err)
  5. }
  6. defer db.Close()
  7. var tweet string
  8. rows, err := db.Query("select tweet from posts where username = ?", "shaw")
  9. if err != nil {
  10. fmt.Println(err)
  11. }
  12. defer rows.Close()
  13. for rows.Next() {
  14. err := rows.Scan(&tweet)
  15. if err != nil {
  16. fmt.Println(err)
  17. }
  18. fmt.Printf("this %s", tweet)
  19. return tweet
  20. }
  21. return ""
  22. }

显示的结果只给我返回了表中的一个值,而不是与"Shaw"相关的其他值。如何获取多个结果?

根据这里的文档,似乎没有什么问题... https://code.google.com/p/go-wiki/wiki/SQLInterface

英文:

I'm trying to fetch data from a table using the sql/db package in Go. My database table contains a username "shaw". There are a few rows with the username shaw with different posts in the post column attached to it. I have the following code:

GO:

  1. func ReadData() string {
  2. db, err := sql.Open("mysql", "user1@/my_db")
  3. if err != nil {
  4. fmt.Println(err)
  5. }
  6. defer db.Close()
  7. var tweet string
  8. rows, err := db.Query("select tweet from posts where username = ?", "shaw")
  9. if err != nil {
  10. fmt.Println(err)
  11. }
  12. defer rows.Close()
  13. for rows.Next() {
  14. err := rows.Scan(&tweet)
  15. if err != nil {
  16. fmt.Println(err)
  17. }
  18. fmt.Printf("this %s", tweet)
  19. return tweet
  20. }
  21. return ""
  22. }

The result shown only gives me 1 value from the table and not the other values associate with "Shaw". How do I fetch more than 1 result?

According to the documentation here there doesn't seem to be anything wrong.. https://code.google.com/p/go-wiki/wiki/SQLInterface

答案1

得分: 4

因为你只返回了第一个推文并退出函数,要返回多个推文,你需要返回一个切片,例如:

  1. func ReadData() (res []string) {
  2. db, err := sql.Open("mysql", "user1@/my_db")
  3. if err != nil {
  4. fmt.Println(err)
  5. }
  6. defer db.Close()
  7. rows, err := db.Query("select tweet from posts where username = ?", "shaw")
  8. if err != nil {
  9. fmt.Println(err)
  10. return
  11. }
  12. defer rows.Close()
  13. var tweet string
  14. for rows.Next() {
  15. err := rows.Scan(&tweet)
  16. if err != nil {
  17. fmt.Println(err)
  18. return
  19. }
  20. fmt.Printf("this %s", tweet)
  21. res = append(res, tweet)
  22. }
  23. return
  24. }
英文:

Because you return the first tweet and exit the function, to return multiple tweets you have to return a slice, for example:

  1. func ReadData() (res []string) {
  2. db, err := sql.Open("mysql", "user1@/my_db")
  3. if err != nil {
  4. fmt.Println(err)
  5. }
  6. defer db.Close()
  7. rows, err := db.Query("select tweet from posts where username = ?", "shaw")
  8. if err != nil {
  9. fmt.Println(err)
  10. return
  11. }
  12. defer rows.Close()
  13. var tweet string
  14. for rows.Next() {
  15. err := rows.Scan(&tweet)
  16. if err != nil {
  17. fmt.Println(err)
  18. return
  19. }
  20. fmt.Printf("this %s", tweet)
  21. res = append(res, tweet)
  22. }
  23. return
  24. }

答案2

得分: 1

OneOfOne的答案很好,但你可能想要更改函数,使其不返回切片,而是将推文发送到一个通道中。这样,你可以在所有推文都发送完之前开始消费结果。在这种情况下,你可能需要像这样的代码:

  1. func ReadData() (res chan<- string) {
  2. db, err := sql.Open("mysql", "user1@/my_db")
  3. if err != nil {
  4. fmt.Println(err)
  5. }
  6. rows, err := db.Query("select tweet from posts where username = ?", "shaw")
  7. if err != nil {
  8. fmt.Println(err)
  9. db.Close()
  10. close(res)
  11. return
  12. }
  13. go func(res chan<- string) {
  14. defer db.Close()
  15. defer rows.Close()
  16. defer close(res)
  17. var tweet string
  18. for rows.Next() {
  19. err := rows.Scan(&tweet)
  20. if err != nil {
  21. fmt.Println(err)
  22. return
  23. }
  24. fmt.Printf("this %s", tweet)
  25. res <- tweet
  26. }
  27. return
  28. }(res)
  29. }

然后,你可以通过更改输入res chan<- string的缓冲区来控制数据库缓冲。根据你的应用程序,你可能不想关闭结果 - 这取决于你。

英文:

OneOfOne's answer is good, but you might want to change the function so that instead of returning a slice, it sends the tweets on a channel. That way, you can start consuming results before they are all done being sent. In that case, you'd want something like:

  1. func ReadData() (res chan&lt;- string) {
  2. db, err := sql.Open(&quot;mysql&quot;, &quot;user1@/my_db&quot;)
  3. if err != nil {
  4. fmt.Println(err)
  5. }
  6. rows, err := db.Query(&quot;select tweet from posts where username = ?&quot;, &quot;shaw&quot;)
  7. if err != nil {
  8. fmt.Println(err)
  9. db.Close()
  10. close(res)
  11. return
  12. }
  13. go func(res chan&lt;- string) {
  14. defer db.Close()
  15. defer rows.Close()
  16. defer close(res)
  17. var tweet string
  18. for rows.Next() {
  19. err := rows.Scan(&amp;tweet)
  20. if err != nil {
  21. fmt.Println(err)
  22. return
  23. }
  24. fmt.Printf(&quot;this %s&quot;, tweet)
  25. res &lt;- tweet
  26. }
  27. return
  28. }(res)
  29. }

Then, you can control the database buffering by changing the buffer of the input res chan&lt;- string. Depending on your application you might not want to close the result - that's up to you.

huangapple
  • 本文由 发表于 2014年8月14日 22:53:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/25311162.html
匿名

发表评论

匿名网友

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

确定