diff --git a/internal/sqladapter/testing/adapter.go.tpl b/internal/sqladapter/testing/adapter.go.tpl
index f9d1af5a6a5c2b21c725db87d33e60eb89e993df..88d431a6e1366ab6887d51b2d0d92bf75a9c9aa2 100644
--- a/internal/sqladapter/testing/adapter.go.tpl
+++ b/internal/sqladapter/testing/adapter.go.tpl
@@ -1099,6 +1099,63 @@ func TestBuilder(t *testing.T) {
 	assert.NoError(t, err)
 	assert.NotZero(t, all)
 
+	// Using explicit iterator and NextScan.
+	iter = sess.SelectFrom("artist").Iterator()
+	var id int
+	var name string
+
+	if Adapter == "ql" {
+		err = iter.NextScan(&name)
+		id = 1
+	} else {
+		err = iter.NextScan(&id, &name)
+	}
+
+	assert.NoError(t, err)
+	assert.NotZero(t, id)
+	assert.NotEmpty(t, name)
+	assert.NoError(t, iter.Close())
+
+	err = iter.NextScan(&id, &name)
+	assert.Error(t, err)
+
+	// Using explicit iterator and ScanOne.
+	iter = sess.SelectFrom("artist").Iterator()
+	id, name = 0, ""
+	if Adapter == "ql" {
+		err = iter.ScanOne(&name)
+		id = 1
+	} else {
+		err = iter.ScanOne(&id, &name)
+	}
+
+	assert.NoError(t, err)
+	assert.NotZero(t, id)
+	assert.NotEmpty(t, name)
+
+	err = iter.ScanOne(&id, &name)
+	assert.Error(t, err)
+
+	// Using explicit iterator and Next.
+	iter = sess.SelectFrom("artist").Iterator()
+
+	var artist map[string]interface{}
+	for iter.Next(&artist) {
+		if Adapter != "ql" {
+			assert.NotZero(t, artist["id"])
+		}
+		assert.NotEmpty(t, artist["name"])
+	}
+	// We should not have any error after finishing successfully exiting a Next() loop.
+	assert.Empty(t, iter.Err())
+
+	for i := 0; i < 5; i++ {
+		// But we'll get errors if we attempt to continue using Next().
+		assert.False(t, iter.Next(&artist))
+		assert.Error(t, iter.Err())
+	}
+
+
 	// Using implicit iterator.
 	q := sess.SelectFrom("artist")
 	err = q.All(&all)
diff --git a/lib/sqlbuilder/builder.go b/lib/sqlbuilder/builder.go
index edeaebc5469d64f60ad4adfc5174e06dae02fda5..1edfd366065c3e77188ff511f94198731d355280 100644
--- a/lib/sqlbuilder/builder.go
+++ b/lib/sqlbuilder/builder.go
@@ -312,6 +312,21 @@ func (s *stringer) compileAndReplacePlaceholders(stmt *exql.Statement) (query st
 	return query
 }
 
+func (iter *iterator) NextScan(dst ...interface{}) error {
+	if ok := iter.Next(); ok {
+		return iter.Scan(dst...)
+	}
+	if err := iter.Err(); err != nil {
+		return err
+	}
+	return db.ErrNoMoreRows
+}
+
+func (iter *iterator) ScanOne(dst ...interface{}) error {
+	defer iter.Close()
+	return iter.NextScan(dst...)
+}
+
 func (iter *iterator) Scan(dst ...interface{}) error {
 	if err := iter.Err(); err != nil {
 		return err
@@ -351,7 +366,6 @@ func (iter *iterator) Err() (err error) {
 }
 
 func (iter *iterator) Next(dst ...interface{}) bool {
-
 	if err := iter.Err(); err != nil {
 		return false
 	}
@@ -368,6 +382,9 @@ func (iter *iterator) Next(dst ...interface{}) bool {
 }
 
 func (iter *iterator) next(dst ...interface{}) error {
+	if iter.cursor == nil {
+		return iter.setErr(db.ErrNoMoreRows)
+	}
 
 	switch len(dst) {
 	case 0:
diff --git a/lib/sqlbuilder/interfaces.go b/lib/sqlbuilder/interfaces.go
index ccdb7c57b515d715a543555cd70d04edb6c7d7f3..094e863991b8225c9e35a350f6da3bbc00efa2c4 100644
--- a/lib/sqlbuilder/interfaces.go
+++ b/lib/sqlbuilder/interfaces.go
@@ -416,6 +416,12 @@ type Iterator interface {
 	// Scan dumps the current result into the given pointer variable pointers.
 	Scan(dest ...interface{}) error
 
+	// NextScan advances the iterator and performs Scan.
+	NextScan(dest ...interface{}) error
+
+	// ScanOne advances the iterator, performs Scan and closes the iterator.
+	ScanOne(dest ...interface{}) error
+
 	// Next dumps the current element into the given destination, which could be
 	// a pointer to either a map or a struct.
 	Next(dest ...interface{}) bool