2

I am using the following query to query the DB. But I get the error sql: expected 0 arguments, got 1.

Following is the code that I am using:

row := DB.QueryRow(`SELECT COUNT(*) FROM Users WHERE Id = "%s";`, userID)
if err != nil {
    return err.Error()
}

I am using the following package and driver

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

Edit:

I also tried with the following query, but I get the same error.

row := DB.QueryRow(`SELECT COUNT(*) FROM Users WHERE Id = "$1";`, userID)
if err != nil {
    return err.Error()
}
  • 1
    not sure if it is DB-dependent but this article suggests using arguments as numbers prefixed with dollar sign: https://www.calhoun.io/querying-for-a-single-record-using-gos-database-sql-package/ – mangusta Aug 03 '20 at 02:23
  • I tried that, but I get the same error. `\`SELECT COUNT(*) FROM Users WHERE Id = "$1";\`, userID`. –  Aug 03 '20 at 02:29
  • Does this answer your question? [Correct way to write a text SQL query in Go](https://stackoverflow.com/questions/36110601/correct-way-to-write-a-text-sql-query-in-go) – Adam Smith Aug 03 '20 at 02:34
  • I tried the approach suggested in that thread but I get same error. –  Aug 03 '20 at 02:45
  • 1
    Please mention the database and the driver used(with versions if possible). – Vaibhav Mishra Aug 03 '20 at 04:12

2 Answers2

2

As suggested in this thread, you basically need to use ? as a placeholder in the Query or QueryRow functions. So, the query above should look like this:

row := DB.QueryRow(`SELECT COUNT(*) FROM Users WHERE Id = ? ;`, userID)
if err != nil {
    return err.Error()
}
1

The reason why your code isn't working is because you are using a formatted string syntax, but nothing to format it. And the reason why no arguments were expected were probably because the correct placeholders weren't used. Try wrapping up the query in a formatter like fmt.Sprintf like:

query := fmt.Sprintf(`SELECT COUNT(*) FROM Users WHERE Id = '%s'`, userID)
row := DB.QueryRow(query)
if err != nil {
    return err.Error()
}

You can also avoid fmt.Sprintf. Instead you can follow a format more specific to the driver you are using. For example

// For "github.com/go-sql-driver/mysql"
row := DB.QueryRow("SELECT COUNT(*) FROM Users WHERE Id=?", userID)

// For "github.com/mattn/go-sqlite3"
row := DB.QueryRow("SELECT COUNT(*) FROM Users WHERE Id=?", userID)

// For "github.com/lib/pq"
row := DB.QueryRow("SELECT COUNT(*) FROM Users WHERE Id=$1", userID)
Vaibhav Mishra
  • 415
  • 3
  • 10
  • I see. I didn't know that different drivers have different placeholder syntax. Thanks for pointing that out. I will also update the question specifying the driver that I used. –  Aug 04 '20 at 05:12
  • Another thing is that when I **tried** to use `fmt.Sprintf` to format my query string, `go` threw errors that I was trying to format a `SQL` string. I guess the `mysql` driver doesn't allow to format in that way. –  Aug 04 '20 at 05:14
  • 1
    @VighneshRaut That's not true. You are allowed to use `fmt.Sprintf` in go with the mysql driver. Maybe you have something in your machine to warn you against possible sql injection vulnerabilities? Speaking of which, `fmt.Sprintf` isn't recommended while querying the db as it isn't safe. – Vaibhav Mishra Aug 04 '20 at 07:56