Codebase list golang-github-denisenkom-go-mssqldb / 3b49436
add documentation and test for reading output parameters from a stored procedure with resultset (#470) Yuki Wong authored 5 years ago Daniel Theophanes committed 5 years ago
2 changed file(s) with 89 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
116116 )
117117 ```
118118
119 ## Reading Output Parameters from a Stored Procedure with Resultset
120
121 To read output parameters from a stored procedure with resultset, make sure you read all the rows before reading the output parameters:
122 ```go
123 sqltextcreate := `
124 CREATE PROCEDURE spwithoutputandrows
125 @bitparam BIT OUTPUT
126 AS BEGIN
127 SET @bitparam = 1
128 SELECT 'Row 1'
129 END
130 `
131 var bitout int64
132 rows, err := db.QueryContext(ctx, "spwithoutputandrows", sql.Named("bitparam", sql.Out{Dest: &bitout}))
133 var strrow string
134 for rows.Next() {
135 err = rows.Scan(&strrow)
136 }
137 fmt.Printf("bitparam is %d", bitout)
138 ```
139
119140 ## Caveat for local temporary tables
120141
121142 Due to protocol limitations, temporary tables will only be allocated on the connection
500500 }
501501 if !match {
502502 t.Errorf("Error '%v', does not match pattern '%v'.", actual, pattern)
503 }
504 })
505 }
506
507 // TestOutputParamWithRows tests reading output parameter before and after
508 // retrieving rows from the result set of a stored procedure. SQL Server sends output
509 // parameters after all the rows are returned. Therefore, if the output parameter
510 // is read before all the rows are retrieved, the value will be incorrect.
511 //
512 // Issue https://github.com/denisenkom/go-mssqldb/issues/378
513 func TestOutputParamWithRows(t *testing.T) {
514 sqltextcreate := `
515 CREATE PROCEDURE spwithoutputandrows
516 @bitparam BIT OUTPUT
517 AS BEGIN
518 SET @bitparam = 1
519 SELECT 'Row 1'
520 END
521 `
522 sqltextdrop := `DROP PROCEDURE spwithoutputandrows;`
523 sqltextrun := `spwithoutputandrows`
524
525 checkConnStr(t)
526 SetLogger(testLogger{t})
527
528 db, err := sql.Open("sqlserver", makeConnStr(t).String())
529 if err != nil {
530 t.Fatalf("failed to open driver sqlserver")
531 }
532 defer db.Close()
533
534 ctx, cancel := context.WithCancel(context.Background())
535 defer cancel()
536
537 db.ExecContext(ctx, sqltextdrop)
538 _, err = db.ExecContext(ctx, sqltextcreate)
539 if err != nil {
540 t.Fatal(err)
541 }
542 defer db.ExecContext(ctx, sqltextdrop)
543
544 t.Run("Retrieve output after reading rows", func(t *testing.T) {
545 var bitout int64 = 5
546 rows, err := db.QueryContext(ctx, sqltextrun, sql.Named("bitparam", sql.Out{Dest: &bitout}))
547 if err != nil {
548 t.Error(err)
549 } else {
550 defer rows.Close()
551 var strrow string
552 for rows.Next() {
553 err = rows.Scan(&strrow)
554 }
555 if bitout != 1 {
556 t.Errorf("expected 1, got %d", bitout)
557 }
558 }
559 })
560
561 t.Run("Retrieve output before reading rows", func(t *testing.T) {
562 var bitout int64 = 5
563 rows, err := db.QueryContext(ctx, sqltextrun, sql.Named("bitparam", sql.Out{Dest: &bitout}))
564 if err != nil {
565 t.Error(err)
566 } else {
567 defer rows.Close()
568 if bitout != 5 {
569 t.Errorf("expected 5, got %d", bitout)
570 }
503571 }
504572 })
505573 }