sijms / go-ora

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

Oracle Sequence with value over 1000000 is not getting mapped to int when using .nextval from dual #429

Closed paulacgates closed 1 year ago

paulacgates commented 1 year ago

After making some tests, i've realized that the new version 2.7.15 is not mapping the sequence to integer when nextval is greater than 1000000 and by consequence, I can't get the value of the .nextval. To work around I have been using the cast() sql function to integer.

Here are the test:

var nextId int  
db.QueryRow("select test_seq.nextval from dual").Scan(&nextId)  
fmt.Printf("%d", nextId)

and the details of my enviromnent:

version OK: 2.7.12 
version that the problem started: 2.7.15
Go version: 1.20.7 

connection setting: 

    urlOptions := map[string]string{

        "language":  "BRAZILIAN PORTUGUESE",

        "territory": "BRAZIL",

        "LOB FETCH": "POST",

    }
ETLJ commented 1 year ago

I am using go 1.21.0 with version 2.7.15 and I see something similar when mapping the table's primary key column to an int:

sql: Scan error on column index 0, name "ID": converting driver.Value type float64 ("2.299362e+06") to a int: invalid syntax

The id for the record I'm testing it out with is 2299362 image

The previous version I was using was 2.7.10 and it works fine there.

Edit: I tried 2.7.14 and I see the same error, but it worked on 2.7.13 Edit2: The Oracle db version is 19c

sijms commented 1 year ago

as you see the error come from sql not the driver column define without precision or scale so this column can accept int or float value. In this case the driver will use type that can accept int or float value which is float64. so in case scale is not defined the driver will use float64 then you should cast float to in

ETLJ commented 1 year ago

as you see the error come from sql not the driver column define without precision or scale so this column can accept int or float value. In this case the driver will use type that can accept int or float value which is float64. so in case scale is not defined the driver will use float64 then you should cast float to in

This was Oracle's default length, precision and scale for an Oracle identity column (auto-generated ids), so from now on anyone using the defaults for their identity columns will have to cast from float to int?

image

paulacgates commented 1 year ago

Just out of curiosity, why in version 2.7.12, the default was mapped as int and why now is being mapped as float?

sijms commented 1 year ago

issue #425 v2.7.12 and before number return as string

sijms commented 1 year ago

the solution is to read the string then search for the point "." if present = float64 otherwise int64

if you have an better ideas please share

ETLJ commented 1 year ago

The error message that I see is

sql: Scan error on column index 0, name "ID": converting driver.Value type float64 ("2.299362e+06") to a int: invalid syntax

and I think that error message is formatted here in database/sql: https://cs.opensource.google/go/go/+/refs/tags/go1.21.0:src/database/sql/convert.go;l=438

The "invalid syntax" at the end of that message looks like the ErrSynax message from the strconv lib: https://pkg.go.dev/strconv#ErrSyntax

The string value of the float64 ends up as "2.299362e+06" which is not valid syntax for the call to strconv.ParseInt

Here's a small example: https://go.dev/play/p/zCCMPBgUCrA

sijms commented 1 year ago

fixed in v2.7.16