Coder Social home page Coder Social logo

goracle's Introduction

WARNING

This repo is frozen, all future modifications will happen in

github.com/go-goracle/goracle

This is for gopkg.in versioning, so you can use

gopkg.in/goracle.v1

for imports! Reasons for this change:

  1. Nicer import path,
  2. Versioned imports - braking changes will go into a new branch, appearing as a new version: gopkg.in/goracle.v2
  3. I've created a new GitHub organization, and the import path no longer contains my name, so the transition of ownership may be easier in the future, if someone with better skills, more time appear to maintain goracle.

goracle

goracle/oracle is a package is a translated version of cx_Oracle (by Anthony Tuininga) converted from C (Python module) to Go.

goracle/godrv is a package which is a database/sql/driver.Driver compliant wrapper for goracle/oracle - passes github.com/bradfitz/go-sql-test (as github.com/tgulacsi/go-sql-test).

There

CHAR, VARCHAR2, NUMBER, DATETIME, INTERVAL simple AND array bind/define. CURSOR, CLOB, BLOB

Not working

Cannot input PLS_INTEGER, only INTEGER (this is OK, as PLS_INTEGER is a PL/SQL type, not an SQL one).

Not working ATM

Nothing I know of.

Not tested (yet)

LONG, LONG RAW, BFILE

Usage and intentions

I haven't had the pressure to force me understanding database/sql - yet. I've ported cx_Oracle because I'm using Python with Oracle most of, and no featureful OCI binding has existed for Go that time. Thus I'm fluent with cx_Oracle and that means goracle/oracle.

BUT I'd start and stick with database/sql as long as it is possible

  • my impression is that Go's standard library is very high quality.

Of course if you need to use Oracle's non-standard features (out bind variables, returning cursors, sending and receiving PL/SQL associative tables...) then goracle/oracle is the straight choice.

For simple (connection, Ping, Select) usage, and testing connection (DSN can be tricky), see conntest.

Changes

With b0219c8f we can reuse statements with different number of bind variables!

Debug

You can build the test executable (for debugging with gdb, for example) with go test -c

You can build a tracing version with the "trace" build tag (go build -tags=trace) that will print out everything before calling OCI C functions.

See c for example.

Install

It is go get'able with go get github.com/tgulacsi/goracle/godrv iff you have Oracle DB installed OR the Oracle's InstantClient both the Basic Client and the SDK (for the header files), too!

  • installed

For environment variables on POSIXy systems, you can try . ./env:

go get github.com/tgulacsi/goracle
cd $GOPATH/src/github.com/tgulacsi/goracle
. ./env
go install ./godrv

Linux

AND you have set proper environment variables:

export CGO_CFLAGS=-I$(dirname $(find $ORACLE_HOME -type f -name oci.h))
export CGO_LDFLAGS=-L$(dirname $(find $ORACLE_HOME -type f -name libclntsh.so\*))
go get github.com/tgulacsi/goracle/godrv

For example, with my XE:

ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe
CGO_CFLAGS=-I/u01/app/oracle/product/11.2.0/xe/rdbms/public
CGO_LDFLAGS=-L/u01/app/oracle/product/11.2.0/xe/lib

With InstantClient:

CGO_CFLAGS=-I/usr/include/oracle/11.2/client64
CGO_LDFLAGS=-L/usr/include/oracle/11.2/client64

RHEL 5

If your git is too old, gopkg.in may present too much hops. You can do

mkdir -p $GOPATH/src/gopkg.in/ && cd $GOPATH/src/gopkg.in && \
	git checkout https://github.com/go-errgo/errgo.git errgo.v1 && \
	cd errgo.v1 && git checkout -f v1
mkdir -p $GOPATH/src/gopkg.in/ && cd $GOPATH/src/gopkg.in && \
	git checkout https://github.com/inconshreveable/log15.git log15.v2 && \
	cd log15.v2 && git checkout -f v2

Mac OS X

For Mac OS X I did the following:

You have to get both the Instant Client Package Basic and the Instant Client Package SDK (for the header files).

Then set the env vars as this (note the SDK here was unpacked into the base directory of the Basic package)

export CGO_CFLAGS=-I/Users/dfils/src/oracle/instantclient_11_2/sdk/include
export CGO_LDFLAGS=-L/Users/dfils/src/oracle/instantclient_11_2
export DYLD_LIBRARY_PATH=/Users/dfils/src/oracle/instantclient_11_2:$DYLD_LIBRARY_PATH

Perhaps this export would work too, but I did not try it. I understand this is another way to do this

export DYLD_FALLBACK_LIBRARY_PATH=/Users/dfils/src/oracle/instantclient_11_2

The DYLD vars are needed to run the binary, not to compile it.

Windows 7 64-bit

Thanks to Johann Kropf!

Requirements

  • mingw-w64
  • msys
  • go
  • Oracle InstantClient Basic 64bit
  • Oracle InstantClient SDK 64bit
  • github.com\tgulacsi\goracle under %GOPATH%

Set CGO_CFLAGS=-IC:\Oracle64Instant\sdk\include Set CGO_LDFLAGS=-LC:\Oracle64Instant\sdk\lib

On Windows the library libclntsh.so does not exist. So change the line in all the source files of github.com\tgulacsi\goracle\oracle

From #cgo LDFLAGS: -lclntsh

to #cgo LDFLAGS: -loci

Create the liboci.a file from the oci.dll by doing

  1. Install Msys from Mingw if not already done
  2. Download gendef utility from http://sourceforge.net/p/mingw-w64/code/HEAD/tree/stable/v3.x/ by "Download snapshot"
  3. Extract the zip-file and copy the folder gendef to your home-directory in Msys
  4. go to the folder gendef and execute ./configure and ./make - gendef.exe will be created
  5. Run: gendef oci.dll - oci.def will be generated
  6. Run: dlltool -D oci.dll -d oci.def -l liboci.a - liboci.a will be generated
  7. copy liboci.a C:\Oracle64Instant\sdk\lib

Build oracle with %GOPATH%\github.com\tgulacsi\goracle\oracle>go install

You can build now your program which imports "github.com/tgulacsi/goracle/oracle"!

goracle's People

Contributors

emicklei avatar tgulacsi avatar viney avatar vsdutka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

goracle's Issues

Looking forward to your new release!

I often use oracle database . now i want to do something using golang.
but there aren't a suitable oracle driver for me.
the gooracle driver is still something wrong on "oracle clob".
Looking forward to your new release.

prepared statements

Everything is working great using goracle as a driver within database/sql

I can get results back but when I go to make a prepared statement I am getting errors. The code is below. When I run it I get:

Doug-Fils-MacBook-Pro:etl dfils$ go run test.go
2013/09/12 09:56:01 Issuing stmt query
2013/09/12 09:56:01 sql: statement expects 0 inputs; got 1
exit status 1

as though it is not seeing the ? for the prepared statement at

x.leg = ?

Issue with goracle or with database/sql (I don't know).. like with me of course. ;)

    stmt, err := db.Prepare(`
 select x.leg, x.site, x.hole, x.core, x.core_type,
 x.section_number, x.section_type,
 s.top_interval*100.0, s.bottom_interval*100.0,
 get_depths(x.section_id,'STD',s.top_interval,0,0) mbsf,
 null,
 avg(decode(cca.analysis_code,'INOR_C',cca.analysis_result)),
 avg(decode(cca.analysis_code,'CaCO3', cca.analysis_result)),
 avg(decode(cca.analysis_code,'TOT_C', cca.analysis_result)),
 avg(decode(cca.analysis_code,'ORG_C', cca.analysis_result)),
 avg(decode(cca.analysis_code,'NIT',   cca.analysis_result)),
 avg(decode(cca.analysis_code,'SUL',   cca.analysis_result)),
 avg(decode(cca.analysis_code,'H',     cca.analysis_result))
 from hole h, section x, sample s,
 chem_carb_sample ccs, chem_carb_analysis cca
 where h.leg = x.leg and h.site = x.site and h.hole = x.hole and
 x.section_id = s.sam_section_id and
 s.sample_id = ccs.sample_id and
 s.location = ccs.location and
 ccs.run_id = cca.run_id
 and x.leg = ?
 and x.site = 999
 and x.hole = upper('A')
 group by x.leg, x.site, x.hole, x.core, x.core_type, x.section_type, x.section_number, s.top_interval, s.bottom_interval, x.section_id
 order by x.leg, x.site, x.hole, x.core,
 x.core_type, x.section_number, s.top_interval
 `)

// stmt, err := db.Prepare("select x.leg, x.site, x.hole, x.core, x.core_type, x.section_number, x.section_type, s.top_interval*100.0, s.bottom_interval*100.0, get_depths(x.section_id,'STD',s.top_interval,0,0) mbsf, null, avg(decode(cca.analysis_code,'INOR_C',cca.analysis_result)), avg(decode(cca.analysis_code,'CaCO3', cca.analysis_result)), avg(decode(cca.analysis_code,'TOT_C', cca.analysis_result)), avg(decode(cca.analysis_code,'ORG_C', cca.analysis_result)), avg(decode(cca.analysis_code,'NIT',   cca.analysis_result)), avg(decode(cca.analysis_code,'SUL',   cca.analysis_result)), avg(decode(cca.analysis_code,'H',     cca.analysis_result)) from hole h, section x, sample s, chem_carb_sample ccs, chem_carb_analysis cca where h.leg = x.leg and h.site = x.site and h.hole = x.hole and x.section_id = s.sam_section_id and s.sample_id = ccs.sample_id and s.location = ccs.location and ccs.run_id = cca.run_id and x.leg = ? and x.site = 999 and x.hole = upper('A') group by x.leg, x.site, x.hole, x.core, x.core_type, x.section_type, x.section_number, s.top_interval, s.bottom_interval, x.section_id order by x.leg, x.site, x.hole, x.core, x.core_type, x.section_number, s.top_interval ")

if err != nil {
    log.Fatal(err)
}

rows, err := stmt.Query(165)
if err != nil {
    log.Printf("Issuing stmt query\n")
    log.Fatal(err)
}
defer rows.Close()

NULL and **time.Time

When Scanning a NULL value into a **time.Time variable, the value of *time.Time is often not nil and pointing to a presumably bogus date. Seems not to occur if all the values in the row are NULL, only if some are.

It occurs when the Scan is done like this:
var date *time.Time
row.Scan(&date)

cgo error or something else?

Hi, I am using oracle times ten database and my code is as follow:

func main() {
        godrv.SetAutoCommit(false)
        db, err := sql.Open("goracle", os.Getenv("ORACLE_DSN"))
        if err != nil {
                log.Println(err)
                os.Exit(1)
        }
        db.SetMaxOpenConns(128)
        db.SetMaxIdleConns(64)
        // 10 go routine insert
        runtime.GOMAXPROCS(4)
        var wg sync.WaitGroup
        log.Println(time.Now())
        var numInsert = 2500
        for i := 0; i < 4; i++ {
                wg.Add(1)
                go func() {
                        tx, err := db.Begin()
                        exit(err)
                        stmt, err := tx.Prepare("INSERT INTO users VALUES(?)")
                        defer stmt.Close()
                        for i := 0; i < numInsert; i++ {
                                _, err = stmt.Exec(time.Now().UnixNano())
                                exit(err)
                        }
                        err = tx.Commit()
                        exit(err)
                        wg.Done()
                }()
        }
        wg.Wait()
        log.Println(time.Now())
}

If I set numInsert to 250, it will not raise any error. But while it's set to 2500 or more, the error is like this:

bc77568c-e472-46e1-b273-407cfa856d6c

a7922410-be36-47cd-b1c1-c8c158961da8

2651f78e-3b56-4424-bae6-7be5d5af9765

19b9d345-5cf9-490f-9e7d-4e5017c351e1

I am not sure if it's due to my misuse of goracle or any other error. I think the code is simple as it is. BTW, if I start more than 4 go routines to insert data into database, it raised the same error which really confused me. Would you help?

ExternalLobVar not thread safe

Minimum program to reproduce:

text := "abcdefghijkl"
stmt, err := conn.Prepare("SELECT TO_CLOB('" + text + "') FROM DUAL")
if err != nil {
    log.Printf("error preparing query1: %v", err)
}
defer stmt.Close()

for i := 0; i < 50; i++ {
    go func() {
        for true {
            var clob *oracle.ExternalLobVar
            if err = stmt.QueryRow().Scan(&clob); err != nil {
                log.Printf("Error scanning clob: %v", err)
            }
            defer clob.Close()
            log.Printf("clob: %v", clob)

            got, err := clob.ReadAll()
            if err != nil {
                log.Printf("error reading clob: %v", err)
            }
            if string(got) != text {
                log.Printf("clob: got %q, awaited %q", got, text)
            }
        }
    }()
}

<-make(chan int)

Output:

2015/01/26 17:13:41 error reading clob: cannot get internal size of <ExternalLobVar of <Variable ClobVar of 0x0>>: -1073741817: invalid handle
2015/01/26 17:13:41 clob: got "", awaited "abcdefghijkl"
2015/01/26 17:13:41 clob: <ExternalLobVar of <Variable ClobVar of 0x0>>
2015/01/26 17:13:41 CheckStatus(-2) @LobGetLength ERR=-1073741817: invalid handle

ORA-22060: argument [2] is an invalid or uninitialized number

Hi

I'm trying a simple select from a NUMBER(10,0) column, but it fails with this error.

I've tried the following configurations:

  • go1.2 linux/amd64 with Oracle Instant Client 64bit 11.2.0.1.0
  • go1.2.1 linux/386 with Oracle Instant Client 32bit 11.2.0.2.0

In both cases the connection is to an Oracle Database 11g Release 11.2.0.1.0 - 64bit Production.

The code is the simplest query possible:

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/tgulacsi/goracle/godrv"
)

func main() {
    conn, err := sql.Open("goracle", "user/pass@server:1521/sid")
    if err != nil {
        fmt.Println("Connection error:", err)
        return
    }
    rows, err := conn.Query("select number_column from some_table")
    if err != nil {
        fmt.Println("Query error:", err)
        return
    }
    fmt.Println("Query OK")
    if !rows.Next() {
        fmt.Println("Empty table")
        return
    }
    var id int64
    err = rows.Scan(&id)
    if err != nil {
        fmt.Printf("Scan error: %s\n", err)
        return
    }
    fmt.Println("Scan OK, got:", id)
}

This is the trace output:

2014/05/05 17:40:18 CTRACE <goracle.Cursor 0 on 0x1b06f98>.internalPrepare("select number_column from some_table")
2014/05/05 17:40:18 CTRACE <goracle.Cursor 0 on 0x1b06f98>.freeHandle(0x0)
2014/05/05 17:40:18 CTRACE internalPrepare.OCIStmtPrepare2(conn=0x1b06f98, &cur=0xc2100442a0, env=0x1b07078, statement="select number_column from some_table", len=44, tag=[48 37 43 224 59 12 150 113], tagLen=8, NTV_SYNTAX, DEFAULT)
2014/05/05 17:40:18 CTRACE internalPrepare done, cur.handle=&
2014/05/05 17:40:18 CTRACE getStatementType.OCIAttrGet(0x1b221a8, HTYPE_STMT, &stt=0xc2100000d0, &vsize=0xc2100000d8, ATTR_SMT_TYPE, errh=0x1b07078)
2014/05/05 17:40:18 CTRACE statement type is 1
2014/05/05 17:40:18 CTRACE OCIStmtGetBindInfo%!(EXTRA *[0]uint8=&[], *[0]uint8=&[], int=8, int=1, *oracle._Ctype_sb4=0xc2100000e0, []*oracle._Ctype_OraText=[<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>], []uint8=[0 0 0 0 0 0 0 0], []*oracle._Ctype_OraText=[<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>], []uint8=[0 0 0 0 0 0 0 0], []uint8=[0 0 0 0 0 0 0 0], []*[0]uint8=[<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>])
2014/05/05 17:40:18 CTRACE <goracle.Cursor & on 0x1b06f98>.Execute; IsOpen? true
2014/05/05 17:40:18 CTRACE <goracle.Cursor & on 0x1b06f98>.internalPrepare("select number_column from some_table")
2014/05/05 17:40:18 CTRACE <goracle.Cursor & on 0x1b06f98>.performBind
2014/05/05 17:40:18 CTRACE bindVarsArr=[]
2014/05/05 17:40:18 CTRACE bindVarsMap=map[]
2014/05/05 17:40:18 CTRACE <goracle.Cursor & on 0x1b06f98>.internalExecute(0)
2014/05/05 17:40:18 CTRACE internalExecute.OCIStmtExecute(conn=0x1b06f98, cur=0x1b221a8, env=0x1b07078, iters=0, rowOff=0, mode=0)
2014/05/05 17:40:18 CTRACE <goracle.Cursor & on 0x1b06f98>.setRowCount statementType=1
2014/05/05 17:40:18 CTRACE performDefine.OCIAttrGet(cur=0x1b221a8, HTYPE_STMT, numParams=0xc210000110, &x=0xc210000118, PARAM_COUNT, env=0x1b07078)
2014/05/05 17:40:18 CTRACE OCIParamGet(cur=0x1b221a8, HTYPE_STMT, env=%!p(string=HTYPE_STMT), param=0x1b07078, position=833492091176)%!(EXTRA uint=1)
2014/05/05 17:40:18 CTRACE OCIAttrGet(parent=0x1b21f98, parentType=7, dst=0xc210000130, osize=0xc210000138, key=2, env=0x1b07078)
2014/05/05 17:40:18 CTRACE <Variable Float of 0x0>.allocateData
2014/05/05 17:40:18 CTRACE OCIAttrGet(parent=0x1b21f98, parentType=7, dst=0xc210000150, osize=0xc210000158, key=6, env=0x1b07078)
2014/05/05 17:40:18 CTRACE OCIAttrGet(parent=0x1b21f98, parentType=7, dst=0xc210000148, osize=0xc210000160, key=5, env=0x1b07078)
2014/05/05 17:40:18 CTRACE OCIDefineByPos(cur=0x1b221a8, defineHandle=0xc21001f288, env=0x1b07078, position=1, dataArr=0xc210020900, bufferSize=22, oracleType=6 indicator=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], aL=<nil> rC=<nil>, DEFAULT)
2014/05/05 17:40:18 CTRACE OCIDescriptorFree(0x1b21f98, DTYPE_PARAM)
2014/05/05 17:40:18 CTRACE OCIAttrGet(parent=0x1b221a8, parentType=4, dst=0xc210000168, osize=0xc210000170, key=18, env=0x1b07078)
2014/05/05 17:40:18 CTRACE OCIParamGet%!(EXTRA *[0]uint8=&[], string=HTYPE_STMT, *[0]uint8=&[], **[0]uint8=0xc210000178, uint=1)
2014/05/05 17:40:18 CTRACE OCIAttrGet(parent=0x1b21f98, parentType=7, dst=0xc2100001b0, osize=0xc2100001b8, key=2, env=0x1b07078)
2014/05/05 17:40:18 CTRACE OCIAttrGet(parent=0x1b21f98, parentType=7, dst=0xc210000180, osize=0xc2100001c0, key=1, env=0x1b07078)
2014/05/05 17:40:18 CTRACE OCIAttrGet(parent=0x1b21f98, parentType=7, dst=0xc210000188, osize=0xc2100001c8, key=286, env=0x1b07078)
2014/05/05 17:40:18 CTRACE OCIAttrGetName%!(EXTRA unsafe.Pointer=0x1b21f98, oracle._Ctype_ub4=7, oracle._Ctype_ub4=4, *[0]uint8=&[], *oracle._Ctype_sword=0xc2100001d8, *oracle._Ctype_ub4=0xc2100001d0)
2014/05/05 17:40:18 CTRACE OCIAttrGet(parent=0x1b21f98, parentType=7, dst=0xc2100001a0, osize=0xc2100001e0, key=6, env=0x1b07078)
2014/05/05 17:40:18 CTRACE OCIAttrGet(parent=0x1b21f98, parentType=7, dst=0xc210000190, osize=0xc2100001e8, key=5, env=0x1b07078)
2014/05/05 17:40:18 CTRACE OCIAttrGet(parent=0x1b21f98, parentType=7, dst=0xc210000198, osize=0xc2100001f0, key=7, env=0x1b07078)
2014/05/05 17:40:18 CTRACE OCIDescriptorFree%!(EXTRA *[0]uint8=&[], string=DTYPE_PARAM)
OK:
2014/05/05 17:40:18 CTRACE fetchvar 0=<Variable Int64 of 0x0>
2014/05/05 17:40:18 CTRACE typ=<Int64 6 var?false char?false>
2014/05/05 17:40:18 CTRACE OCIStmtFetch(cur=0x1b221a8, env=0x1b07078, numRows=50, FETCH_NEXT, DEFAULT)
2014/05/05 17:40:18 CTRACE OCIAttrGet(parent=0x1b221a8, parentType=4, dst=0xc2100001f8, osize=0xc210000200, key=9, env=0x1b07078)
2014/05/05 17:40:18 CTRACE <Variable Int64 of 0x0>.verifyFetch(0) varlength? false
id -1
2014/05/05 17:40:18 CTRACE <Variable Int64 of 0x0>.verifyFetch(1) varlength? false
2014/05/05 17:40:18 CheckStatus(-1) ERR=@numberToInt 22060: [-1] ORA-22060: argument [2] is an invalid or uninitialized number
ORA-22060: argument [2] is an invalid or uninitialized number
2014/05/05 17:40:18 <Int64 6 var?false char?false>.getSingleValueInto dest=-1 err=@numberToInt 22060: [-1] ORA-22060: argument [2] is an invalid or uninitialized number
ORA-22060: argument [2] is an invalid or uninitialized number
2014/05/05 17:40:18 CTRACE <goracle.Cursor & on 0x1b06f98>.Close
2014/05/05 17:40:18 CTRACE <goracle.Cursor & on 0x1b06f98>.freeHandle(0x1b221a8)
2014/05/05 17:40:18 CTRACE OCIStmtRelease(cur=0x1b221a8, env=0x1b07078, stmtT="0%+\xe0;\f\x96q", len(stmtT)=8)

Is that need to free env.handle ?

We conducted a concurrent test and found that memory up.
Then we adjust the code and found the problem solved.
Do you have a better solution?

code :
func (env *Environment) free() {
if env.errorHandle != nil {
C.OCIHandleFree(unsafe.Pointer(env.errorHandle), C.OCI_HTYPE_ERROR)
}
if env.handle != nil {
C.OCIHandleFree(unsafe.Pointer(env.handle), C.OCI_HTYPE_ENV)
}
env.numberToStringFormatBuffer = nil
env.numberFromStringFormatBuffer = nil
env.nlsNumericCharactersBuffer = nil
}

get 'nothing to build'

vagrant@packer-golang-webapp:tgulacsi$ go get github.com/tgulacsi/goracle
package github.com/tgulacsi/goracle
imports github.com/tgulacsi/goracle
imports github.com/tgulacsi/goracle: no buildable Go source files in /home/vagrant/go/src/github.com/tgulacsi/goracle
vagrant@packer-golang-webapp:tgulacsi$

I've installed the instaclient and I can connect to my DB. There could still easily be a misconfig but 'no buildable' source files' seems an odd error.

callBuildStatement uses wrong argument numbering in case of Function call

This problem manifests itself as a "panic: runtime error: index out of range".

I have traced this problem to a miscalculation of the argument index in the callBuildStatement function. In case of a function, the argNum has an invalid value and needs to be compensated for the fact that the returnValue is bound to 1.

I have created a fix and test for this which I will submit next.

FAIL: TestCursorOut

error executing DECLARE
 v_cur SYS_REFCURSOR;
 BEGIN
 OPEN v_cur FOR
 SELECT * FROM all_objects;
 :1 := v_cur;
 END;: unhandled data type *oracle.Cursor

my os: windows 7 64bit
oracle SDK version: 11.2

cannot find -lclntsh on Windows

I have the basic client and the SDK but I'm missing libclntsh. Any ideas?

go run mycode.go
# github.com/tgulacsi/goracle/oracle
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
collect2.exe: error: ld returned 1 exit status

go version go1.1.1 windows/amd64

Need to close the cursor in driver.go?

// commits currently opened transaction
func (t tx) Commit() error {
if t.cx != nil && t.cx.IsConnected() {
return t.cx.NewCursor().Execute("COMMIT", nil, nil)
}
return nil
}

still have issue on clob field?

maybe there are still some issue on clob. the following is my example. what wrong with it?
func main() {
db, err := sql.Open("goracle", "user/pwd@ORCL1")
if err != nil {
log.Fatal(err)
}
rows, err := db.Query(select ID,CONTENT from ARTICLE_INFO) //content is a clob field

if err != nil {
    log.Fatal(err)
}
defer db.Close()
var f1 string
var f2 string
fout,err := os.Create("f:/test.txt")  
defer fout.Close()
for rows.Next() {
    rows.Scan(&f1, &f2)
    fout.WriteString(f1+"__"+f2+"\r\n")  //f2 is nothing, the length is 0, why? the ID field is ok.
} 

}

Why i get nothing from clob?

conn, err := connect.GetConnection("root/root@ORCL1")
defer conn.Close()
qry := "SELECT content FROM  article_iinfo"   //content is a clob field
rows, err := conn.Query(qry)
var (
    owner oracle.ExternalLobVar
)
for rows.Next() {
    if err = rows.Scan(&owner); err != nil {
        log.Println("error fetching: %s", err)
    }
    log.Printf(`row: %#v"`, owner)
}

// the error is:" row: oracle.ExternalLobVar{lobVar:(*oracle.Variable)(nil), pos:0x0, internalFetchNum:0x0, sFile:false, readPos:0}"
//I use goracle under win xp 32bit

libclntsh.so problem

I've download the instant client from oracle download site and run the script env.sh then set the system variable by export. When I run go install -x in the oracle directory, I got these errors. Would you mind helping me? BTW, I successfully compile goracle and use it in another machine.
0379edcd-b4c8-4fdb-9053-bdb27302af0b

connection string

what's the equivalence of "db = cx_Oracle.connect('user', 'passwd', '211.69.240.2/dbname')" which works fine in cx_Oracle?

help!

THANKS.

Scanning NULL dates

When scanning NULL dates with the SQL driver using conn.Query, NULL values are not (always) scanned correctly. The issue seems to occur when the a date column in a table is as follows:

  1. NULL
  2. 14-AUG-2014
  3. NULL
  4. NULL
  5. ...

The first NULL value will be scanned as zero time, the second value would be correct as well. The third and fourth value seem to be filled with the same date as the second value. When casting the date variable to_char in the query, the NULL values are handled correctly so the problem seems to occur specifically with dates (perhaps intervals? I have not tested these). It's also all fine if scanning a single date value with QueryRow.

ORA-01458: invalid length inside variable character string

func TestCURD(t *testing.T) {
    // open
    db, err := sql.Open("goracle", "xxxxxxxxxxx")
    if err != nil {
        t.Fatal("Open: ", err)
        return
    }
    defer db.Close()

    // drop
    if _, err = db.Exec(`drop table tb_test`); err != nil {
        t.Fatal("Drop: ", err)
        return
    }

    // create
    if _, err = db.Exec(`create table tb_test(userid number(16) not null)`); err != nil {
        t.Fatal("Create: ", err)
        return
    }

    // TODO: error(ORA-01458: invalid length inside variable character string)
    // length is 12, ok(123456789012)
    // length is more than 12, fail(1234567890123)
    var userid uint64 = 1234567890123
    // insert
    if _, err = db.Exec(`insert into tb_test(userid) values(:1)`, userid); err != nil {
        t.Fatal("Insert: ", err)
        return
    }

    // select
    row := db.QueryRow(`select userid from tb_test where userid = :1`, userid)

    var id uint64
    if err = row.Scan(&id); err != nil {
        t.Fatal("Select: ", err)
        return
    }

    fmt.Println(id)
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.