SQL选择-返回的总行数

Using the database/sql package and drivers for Postgres and Mysql I want to achieve the following. I want to be able to Select one row and know that there is either zero rows, one row, or more than one row. the QueryRow function does not achieve that, because as far as I can ascertain, it will return one row without error regardless of if there is more than one row. For my situation, more than one row may be an error, and I want to know about it. I want to create a general function to do this.

I looked at creating a function that uses the Query function, but I do not know how to return the first row if there is more than one row. I want to return the fact that there is more than one row, but I also want to return the first row. To determine that there is more than one row, I have to do a Next, and that overwrites the first row. Obviously I can achieve this without creating a general function, but I want a function to do it because I need to do this in a number of places

Could someone please explain to me how to achieve this. IE. To return the first row from a function when a successful Next has been done or the Next returned nothing.

I'm using both database/sql & MySQLDriver to achieve this. You can download MySQLDriver at https://github.com/go-sql-driver/ .

I wrote execQuery function myself to get one or more rows from database. It's based on MySQL but I think it can also used to Postgres with similar implement.

Assume you have a DB table named test, and have rows named id, name, age.

Code:

var db *sql.DB // it should be initialized by "sql.Open()"

func execQuery(SQL string, args ...interface{}) (rows *sql.Rows, is_succeed bool) {
  rows, err := db.Query(SQL, args...)
  var ret bool
  if err == nil && rows != nil { // if DB query error rows will be nil, it will return false
    ret = true
  } else {
    ret = false
  }

  return rows, ret
}

Usage:

var name, age string
rows, is_succeed = execQuery("SELECT `name`, `age` FROM `test` WHERE `id` = ?", "123")
if !is_succeed {
  // error
  return 
}
for rows.Next() { // if have zero result rows, this for route won't execute
  err := rows.Scan(&name, &age)
  // check if has error & do something
}

If you want to know how much rows returned, just add a counter in for route, use SQL can also achieve this.

sql.Rows likes a list structure, rows *sql.Rows points on first row of returned rows. Use rows.Next() to traverse every rows. I think that's what you've asked.

If you really want to know rows count very often, using a cache mechanic like memcacheDB or Redis or just implement a simple counter yourself can help you solve the problem.