handling database.Query empty set

545 views
Skip to first unread message

Andy Hall

unread,
Sep 12, 2020, 3:16:10 PM9/12/20
to golang-nuts
the database.Query func does not return ErrNoRows unlike the database.QueryRow func so how to I handle an empty set when I wish to run a query which returns multiple rows...

// tell other players in the room you have entered
rows_users, err := database.Query("SELECT username FROM users WHERE room = ? AND username != ?", room, username)
// handle an empty set
if err != nil {
        if err == sql.ErrNoRows {
                fmt.Println("EMPTY SET")
        } else {
                fmt.Println(err)
                return
        }

The string "EMPTY SET" is never printed as the condition is never set...so continues to run through the if statement.

Surely there is is way to handle no rows with Query ??

Martin Schnabel

unread,
Sep 12, 2020, 4:53:28 PM9/12/20
to Andy Hall, golang-nuts
hi Andy,

when you take a look at the documentation of the Rows type returned by
Query you will see a helpful example of its common use, appending the
scanned results into a slice. my recommendation would be to follow this
example and then check if the len(slice) == 0 to detect an empty set.

if you don't actually need the results scanned into a go slice, consider
using query row with a sql select count(*) … query and scan, then check
the resulting integer.

have fun!
> --
> You received this message because you are subscribed to the Google
> Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to golang-nuts...@googlegroups.com
> <mailto:golang-nuts...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/6d6c7d54-1a4b-4f07-bf22-8523045ce543n%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/6d6c7d54-1a4b-4f07-bf22-8523045ce543n%40googlegroups.com?utm_medium=email&utm_source=footer>.

Andy Hall

unread,
Sep 13, 2020, 4:19:23 AM9/13/20
to golang-nuts
thanks martin...it seems with no query handling the database Next func does not run anyway as the rows evaluate to false in the for loop...

// tell other players in the room you have entered
rows_users, err := database.Query("SELECT username FROM users WHERE room = ? AND username != ?", room, username)
// if the user from the db is connected then send them a message
var user string
for rows_users.Next() {
rows_users.Scan(&user)
if conn, ok := m[user]; ok {
conn.Write([]byte(string(username + " has entered the room\n# ")))
}
}

I should probably print something in the loop to confirm but I certainly don't get any null pointer connection errors so may just comment this for clarity and leave it. I guess it saves more code ;-)

Martin Schnabel

unread,
Sep 13, 2020, 5:49:57 AM9/13/20
to golan...@googlegroups.com
sorry Andy,

it seems i haven't read your example carefully enough. your question was
what to do if the query returns multiple rows. i tried to explain that.

however the query in your example looks like it will only ever return a
single row, because you probably marked the username column in your
users table as unique. for that use QueryRow, which is just a convenient
wrapper function for querying a single result row.

you can discover this fact through the documentation. in
https://godoc.org/database/sql#Row you can click on the Scan method name
link to get to the source code of that method
https://golang.org/src/database/sql/sql.go#L3196 and see how it uses
Rows to scan a single result or return the ErrNoRows.

both documentation and source code of the standard library are easy to
discover and read compared to most other languages. i hope this tip
might help you answer other questions yourself as well.

have fun!
> https://groups.google.com/d/msgid/golang-nuts/0a03fd9c-b614-49ee-9d07-a7f44299fd7en%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/0a03fd9c-b614-49ee-9d07-a7f44299fd7en%40googlegroups.com?utm_medium=email&utm_source=footer>.

Andy Hall

unread,
Sep 13, 2020, 6:53:50 AM9/13/20
to golang-nuts
I can assure you my query returns multiple rows which I why I then iterate around the result set and pass to conn.Write in a loop...I am aware of QueryRow and use it elsewhere...but agreed I should perhaps RTFM a bit more thanks !!
Reply all
Reply to author
Forward
0 new messages