@@ -15,6 +15,12 @@ import (
1515 "github.com/vinovest/sqlx/reflectx"
1616)
1717
18+ // ErrMultiRows is returned by functions which are expected to work with result sets
19+ // that only contain a single row but multiple rows were returned.
20+ // This typically indicates an issue with the query such as a missing join criteria or
21+ // limit condition or the use of Get(...) when Select(...) was intended.
22+ var ErrMultiRows = errors .New ("sql: multiple rows returned" )
23+
1824// Although the NameMapper is convenient, in practice it should not
1925// be relied on except for application code. If you are writing a library
2026// that uses sqlx, you should be aware that the name mappings you expect
@@ -175,6 +181,7 @@ type Row struct {
175181
176182// Scan is a fixed implementation of sql.Row.Scan, which does not discard the
177183// underlying error from the internal rows object if it exists.
184+ // Returns ErrMultiRows if the result set contains more than one row.
178185func (r * Row ) Scan (dest ... interface {}) error {
179186 if r .err != nil {
180187 return r .err
@@ -206,10 +213,16 @@ func (r *Row) Scan(dest ...interface{}) error {
206213 }
207214 return sql .ErrNoRows
208215 }
209- err := r .rows .Scan (dest ... )
210- if err != nil {
216+ if err := r .rows .Scan (dest ... ); err != nil {
217+ return err
218+ }
219+
220+ if r .rows .Next () {
221+ return ErrMultiRows
222+ } else if err := r .rows .Err (); err != nil {
211223 return err
212224 }
225+
213226 // Make sure the query can be processed to completion with no errors.
214227 if err := r .rows .Close (); err != nil {
215228 return err
@@ -352,7 +365,7 @@ func (db *DB) Select(dest interface{}, query string, args ...interface{}) error
352365
353366// Get using this DB.
354367// Any placeholder parameters are replaced with supplied args.
355- // An error is returned if the result set is empty.
368+ // An error is returned if the result set is empty or contains more than one row .
356369func (db * DB ) Get (dest interface {}, query string , args ... interface {}) error {
357370 return Get (db , dest , query , args ... )
358371}
@@ -483,7 +496,7 @@ func (tx *Tx) QueryRowx(query string, args ...interface{}) *Row {
483496
484497// Get within a transaction.
485498// Any placeholder parameters are replaced with supplied args.
486- // An error is returned if the result set is empty.
499+ // An error is returned if the result set is empty or contains more than one row .
487500func (tx * Tx ) Get (dest interface {}, query string , args ... interface {}) error {
488501 return Get (tx , dest , query , args ... )
489502}
@@ -551,7 +564,7 @@ func (s *Stmt) Select(dest interface{}, args ...interface{}) error {
551564
552565// Get using the prepared statement.
553566// Any placeholder parameters are replaced with supplied args.
554- // An error is returned if the result set is empty.
567+ // An error is returned if the result set is empty or contains more than one row .
555568func (s * Stmt ) Get (dest interface {}, args ... interface {}) error {
556569 return Get (& qStmt {s }, dest , "" , args ... )
557570}
@@ -727,7 +740,7 @@ func Select(q Queryer, dest interface{}, query string, args ...interface{}) erro
727740// to dest. If dest is scannable, the result must only have one column. Otherwise,
728741// StructScan is used. Get will return sql.ErrNoRows like row.Scan would.
729742// Any placeholder parameters are replaced with supplied args.
730- // An error is returned if the result set is empty.
743+ // An error is returned if the result set is empty or contains more than one row .
731744func Get (q Queryer , dest interface {}, query string , args ... interface {}) error {
732745 r := q .QueryRowx (query , args ... )
733746 return r .scanAny (dest , false )
0 commit comments