Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Incorrect RowsAffected() result after updated #204

Open
targc opened this issue Jul 9, 2024 · 3 comments
Open

Incorrect RowsAffected() result after updated #204

targc opened this issue Jul 9, 2024 · 3 comments

Comments

@targc
Copy link

targc commented Jul 9, 2024

Describe the bug
RowsAffected() returned incorrect value.

To Reproduce

package main

import (
	"context"
	"database/sql"
	"fmt"
	"log"

	_ "github.com/microsoft/go-mssqldb"
)

func main() {
	server := "???"
	user := "???"
	password := "???"
	port := 1433

	connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d", server, user, password, port)

	conn, err := sql.Open("mssql", connString)

	if err != nil {
		panic(err)
	}

	defer conn.Close()

	ctx := context.Background()

	countrow := conn.QueryRow("select count(id) from objects where id = 1;")

	if err := countrow.Err(); err != nil {
		panic(err)
	}

	var count int64

	err = countrow.Scan(&count)

	if err != nil {
		panic(err)
	}

	log.Println("count", count) // output: 1

	result, err := conn.ExecContext(ctx, "update objects set value = 'test' where id = 1;")

	if err != nil {
		panic(err)
	}

	rowsAffected, _ := result.RowsAffected()

	log.Println("rowsAffected", rowsAffected) // output: 3
}

Output

2024/07/09 13:28:15 count 1
2024/07/09 13:28:15 rowsAffected 3

Expected behavior
Following the reproduce code, it should be 1 that returned from result.RowsAffected().

Further technical details

SQL Server version: SQL Server 2017
go-mssqldb: v1.7.2

@shueybubbles
Copy link
Collaborator

thx for opening an issue!
What was the last version of the driver you used where it returned the correct value?

@shueybubbles
Copy link
Collaborator

Can you add a logger to your repro and add the traces here?
You should see traces like this:

e:\git\go-mssqldb\tds_test.go:387: 2024-07-09 17:22:09.5018429 -0500 CDT m=+1.289748201 [token.go:1049]: got DONE or DONEPROC status=16
    e:\git\go-mssqldb\tds_test.go:387: 2024-07-09 17:22:09.5018429 -0500 CDT m=+1.289748201 [token.go:1061]: (Rows affected: 1)
    e:\git\go-mssqldb\tds_test.go:387: 2024-07-09 17:22:09.5018429 -0500 CDT m=+1.289748201 [mssql.go:528]: update #foo set val = N'test' where bar = 1
    e:\git\go-mssqldb\tds_test.go:387: 2024-07-09 17:22:09.6575046 -0500 CDT m=+1.445412201 [token.go:993]: got token tokenDone
    e:\git\go-mssqldb\tds_test.go:387: 2024-07-09 17:22:09.658402 -0500 CDT m=+1.446309601 [token.go:1049]: got DONE or DONEPROC status=16
    e:\git\go-mssqldb\tds_test.go:387: 2024-07-09 17:22:09.658402 -0500 CDT m=+1.446309601 [token.go:1061]: (Rows affected: 1)
    e:\git\go-mssqldb\tds_test.go:387: 2024-07-09 17:22:09.7354126 -0500 CDT m=+1.523321301 [token.go:993]: got token tokenEnvChange

I can't reproduce the issue when I modify TestAffectedRows. This version of the test passes:

func TestAffectedRows(t *testing.T) {
	conn, logger := open(t)
	defer conn.Close()
	defer logger.StopLogging()

	tx, err := conn.Begin()
	if err != nil {
		t.Fatal("Begin tran failed", err)
	}
	defer tx.Rollback()

	res, err := tx.Exec("create table #foo (bar int, val nvarchar(10) null)")
	if err != nil {
		t.Fatal("create table failed")
	}
	n, err := res.RowsAffected()
	if err != nil {
		t.Fatal("rows affected failed")
	}
	if n != 0 {
		t.Error("Expected 0 rows affected, got ", n)
	}

	res, err = tx.Exec("insert into #foo (bar) values (1)")
	if err != nil {
		t.Fatal("insert failed")
	}
	n, err = res.RowsAffected()
	if err != nil {
		t.Fatal("rows affected failed")
	}
	if n != 1 {
		t.Error("Expected 1 row affected, got ", n)
	}

	res, err = tx.Exec("insert into #foo (bar) values (@p1)", 2)
	if err != nil {
		t.Fatal("insert failed", err)
	}
	n, err = res.RowsAffected()
	if err != nil {
		t.Fatal("rows affected failed")
	}
	if n != 1 {
		t.Error("Expected 1 row affected, got ", n)
	}
	// Regression test for https://github.com/microsoft/go-mssqldb/issues/204
	countrow := tx.QueryRow("select count(bar) from #foo where bar = 1;")
	if err := countrow.Err(); err != nil {
		t.Fatal("QueryRow failed ", err)
	}
	var count int64
	err = countrow.Scan(&count)
	if err != nil || count != 1 {
		t.Fatal("Unexpected error or count from QueryRow:", err, count)
	}
	res, err = tx.Exec("update #foo set val = N'test' where bar = 1")
	if err != nil {
		t.Fatal("update failed", err)
	}
	n, err = res.RowsAffected()
	if err != nil {
		t.Fatal("rows affected failed after update")
	}
	if n != 1 {
		t.Error("Expected 1 row affected for update, got ", n)
	}

}

@brijesh-amin
Copy link

Not able to re produce

image

docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Test1234@" -p 1433:1433 mcr.microsoft.com/mssql/server:2017-latest

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants