sijms / go-ora

Pure go oracle client
MIT License
786 stars 174 forks source link

Named Args Being Passed Positionally #448

Closed CharliePlate closed 11 months ago

CharliePlate commented 11 months ago

Hello,

First wanted to say thanks for the hard work that goes into this package. Packaging the entire driver into Go has made distribution of our application so much easier, so we really appreciate the time you have put in.

I am running into an issue with Named Args being passed Positionally, where I believe I am following the correct syntax. Some support would be greatly appreciated

Here is a really simplified example of what I am trying to accomplish:

db, _ := sql.Open("oracle", url)
tx, _ := db.Begin()
s := `
    Begin
      Select 'a', 'b' into :aVar, :bVar from dual;
    End;
`
var aVar, bVar string
tx.Exec(s, sql.Named("bVar", go_ora.Out{Dest: &bVar, Size: 5}), sql.Named("aVar", go_ora.Out{Dest: &aVar, Size: 5}))
fmt.Printf("aVar: %s, bVar: %s\n", aVar, bVar)

The Expectation would be that aVar would contain a and bVar would contain b. In practice, however, this fmt.Printf prints aVar: b, bVar: a, meaning that the variables were passed positionally, (see in the example that bVar is first).

Please let me know if there is anything I am missing here. This is withDatabase Version: 19.0.0.0.0

Thank you!

sijms commented 11 months ago

code:

package main

import (
    "database/sql"
    "fmt"
    go_ora "github.com/sijms/go-ora/v2"
    "os"
    "time"
)

func exec(db *sql.DB) error {
    t := time.Now()
    sqlText := `BEGIN
    SELECT 'a', 'b' into :aVar, :bVar FROM DUAL;
    END;`
    var aVar, bVar string
    _, err := db.Exec(sqlText, sql.Named("bVar", go_ora.Out{Dest: &bVar, Size: 5}),
        sql.Named("aVar", go_ora.Out{Dest: &aVar, Size: 5}))
    if err != nil {
        return err
    }
    fmt.Println("aVar: ", aVar, "\tbVar: ", bVar)
    fmt.Println("finish exec: ", time.Now().Sub(t))
    return nil
}
func main() {
    db, err := sql.Open("oracle", os.Getenv("DSN"))
    if err != nil {
        fmt.Println("can't connect: ", err)
        return
    }
    defer func() {
        err = db.Close()
        if err != nil {
            fmt.Println("can't close connection: ", err)
        }
    }()
    err = exec(db)
    if err != nil {
        fmt.Println("can't exec: ", err)
        return
    }

}

result:

aVar:  a        bVar:  b
finish exec:  1.286287703s
CharliePlate commented 11 months ago

Thank you for the quick response.

It seems my project was using an old version, which seeing your response prompted me to double check. After updating, this is working as intended. Thank you for testing with me and apologies for my ignorance.