Skip to content

Commit

Permalink
fix when passing on output parameter will give ttc buffer error
Browse files Browse the repository at this point in the history
  • Loading branch information
sijms committed Aug 2, 2023
1 parent 29c7591 commit 9eba2e1
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 53 deletions.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,38 @@
always ensure that you get latest release
- See examples for more help
```
### version 2.7.11
* add support for DBMS_OUTPUT
```golang
import (
"database/sql"
db_out "github.com/sijms/go-ora/dbms_output"
_ "github.com/sijms/go-ora/v2"
"os"
)

// create new output
// conn is *sql.DB
// bufferSize between 2000 and 32767
output, err := db_out.NewOutput(conn, 0x7FFF)

// close before exit
defer func() {
err = output.Close()
}()

// put some line
err = exec_simple_stmt(conn, `BEGIN
DBMS_OUTPUT.PUT_LINE('this is a test');
END;`)

// get data as string
line, err := output.GetOutput()

// or print it to io.StringWriter
err = output.Print(os.Stdout)
```
* complete code found in examples/dbms_output/main.go
### version 2.7.7:
* add support for CLOB/BLOB in UDT
* add support for UDT array as output parameters
Expand Down
70 changes: 70 additions & 0 deletions examples/dbms_output/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package main

import (
"database/sql"
"fmt"
db_out "github.com/sijms/go-ora/dbms_output"
_ "github.com/sijms/go-ora/v2"
"os"
)

func exec_simple_conn(conn *sql.DB, texts ...string) error {
var err error
for _, text := range texts {
_, err = conn.Exec(text)
if err != nil {
return err
}
}
return err
}
func main() {
conn, err := sql.Open("oracle", os.Getenv("DSN"))
if err != nil {
fmt.Println("error in connection: ", err)
return
}
defer func() {
err = conn.Close()
if err != nil {
fmt.Println("error in close: ", err)
}
}()
output, err := db_out.NewOutput(conn, 0x7FFF)
if err != nil {
fmt.Println("can't init DBMS_OUTPUT: ", err)
return
}
defer func() {
err = output.Close()
if err != nil {
fmt.Println("can't end dbms_output: ", err)
}
}()
err = exec_simple_conn(conn, `BEGIN
DBMS_OUTPUT.PUT_LINE('this is a test');
END;`)
if err != nil {
fmt.Println("can't write output: ", err)
return
}
line, err := output.GetOutput()
if err != nil {
fmt.Println("can't get output: ", err)
return
}
fmt.Print(line)
err = exec_simple_conn(conn, `BEGIN
DBMS_OUTPUT.PUT_LINE('this is a test2');
END;`)
if err != nil {
fmt.Println("can't write output: ", err)
return
}
err = output.Print(os.Stdout)
if err != nil {
fmt.Println("can't print: ", err)
return
}

}
89 changes: 36 additions & 53 deletions v2/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,61 +353,44 @@ func NewStmt(text string, conn *Connection) *Stmt {
}

func (stmt *Stmt) writePars() error {
if len(stmt.Pars) > 0 {
session := stmt.connection.session
session.PutBytes(7)
for _, par := range stmt.Pars {
if par.Flag == 0x80 {
continue
}
if !stmt.parse && par.Direction == Output && stmt.stmtType != PLSQL {
continue
}
if par.DataType == REFCURSOR {
session.PutBytes(1, 0)
} else if par.Direction == Input &&
(par.DataType == OCIClobLocator || par.DataType == OCIBlobLocator || par.DataType == OCIFileLocator) {
session.PutUint(len(par.BValue), 2, true, true)
session.PutClr(par.BValue)
session := stmt.connection.session
buffer := bytes.Buffer{}
for _, par := range stmt.Pars {
if par.Flag == 0x80 {
continue
}
if !stmt.parse && par.Direction == Output && stmt.stmtType != PLSQL {
continue
}
if par.DataType == REFCURSOR {
session.WriteBytes(&buffer, 1, 0)
} else if par.Direction == Input &&
(par.DataType == OCIClobLocator || par.DataType == OCIBlobLocator || par.DataType == OCIFileLocator) {
session.WriteUint(&buffer, len(par.BValue), 2, true, true)
session.WriteClr(&buffer, par.BValue)
} else {
if par.cusType != nil {
session.WriteBytes(&buffer, 0, 0, 0, 0)
size := len(par.BValue)
session.WriteUint(&buffer, size, 4, true, true)
session.WriteBytes(&buffer, 1, 1)
session.WriteClr(&buffer, par.BValue)
} else {
if par.cusType != nil {
//size := len(par.BValue) + 7
session.PutBytes(0, 0, 0, 0)
size := len(par.BValue)
session.PutUint(size, 4, true, true)
session.PutBytes(1, 1)
session.PutClr(par.BValue)
//tempBuffer := bytes.Buffer{}
//if par.MaxNoOfArrayElements > 0 {
// tempBuffer.Write([]byte{0x84, 0x1, 0xfe})
//} else {
// tempBuffer.Write([]byte{0x84, 0x1, 0xfe})
//}
//session.WriteUint(&tempBuffer, size, 4, true, false)
//tempBuffer.Write(par.BValue)
//session.PutClr(tempBuffer.Bytes())
//session.PutBytes(par.BValue...)
} else {
if par.MaxNoOfArrayElements > 0 {
if par.BValue == nil {
session.PutBytes(0)
} else {
session.PutBytes(par.BValue...)
}
if par.MaxNoOfArrayElements > 0 {
if par.BValue == nil {
session.WriteBytes(&buffer, 0)
} else {
session.PutClr(par.BValue)
session.WriteBytes(&buffer, par.BValue...)
}
} else {
session.WriteClr(&buffer, par.BValue)
}
}
//if par.DataType != RAW {
//
//}
}
//for _, par := range stmt.Pars {
// if par.DataType == RAW {
// session.PutClr(par.BValue)
// }
//}
}
if buffer.Len() > 0 {
session.PutBytes(7)
session.PutBytes(buffer.Bytes()...)
}
return nil
}
Expand All @@ -426,16 +409,16 @@ func (stmt *Stmt) write() error {
session.PutBytes(3, 0x4E, 0)
count = stmt._noOfRowsToFetch
exeOf = 0x20

if stmt._hasReturnClause || stmt.stmtType == PLSQL || stmt.disableCompression {
exeOf |= 0x40000
}
} else {
session.PutBytes(3, 4, 0)
}
if stmt.connection.autoCommit {
execFlag = 1
}
if stmt._hasReturnClause || stmt.stmtType == PLSQL || stmt.disableCompression {
exeOf |= 0x40000
}

session.PutUint(stmt.cursorID, 2, true, true)
session.PutUint(count, 2, true, true)
session.PutUint(exeOf, 2, true, true)
Expand Down

0 comments on commit 9eba2e1

Please sign in to comment.