Pure Go Oracle database driver for database/sql.
go get github.com/sijms/go-ora/v2Requires Oracle server 10.2+. See v3 for the latest version with Oracle 23ai support.
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/sijms/go-ora/v2"
)
func main() {
connStr := "oracle://user:pass@server:1521/service"
db, err := sql.Open("oracle", connStr)
if err != nil {
log.Fatal(err)
}
defer db.Close()
if err := db.Ping(); err != nil {
log.Fatal(err)
}
var version string
err = db.QueryRow("SELECT * FROM v$version").Scan(&version)
if err != nil {
log.Fatal(err)
}
fmt.Println(version)
}Build connection strings with go_ora.BuildUrl or go_ora.BuildJDBC:
// Basic
connStr := go_ora.BuildUrl("server", 1521, "service", "user", "pass", nil)
// With options
connStr := go_ora.BuildUrl("server", 1521, "service", "user", "pass", map[string]string{
"SSL": "true",
"SSL VERIFY": "false",
"WALLET": "/path/to/wallet",
"TIMEOUT": "60",
"TRACE FILE": "trace.log",
})
// JDBC string
connStr := go_ora.BuildJDBC("user", "pass", "JDBC_STRING", nil)| Option | Description | Default |
|---|---|---|
TIMEOUT |
Socket read/write timeout (seconds, 0 = disabled) | 15 |
CONNECTION TIMEOUT |
Connection timeout (seconds, 0 = disabled) | 60 |
FAILOVER |
Reconnect attempts on connection loss | 0 |
SSL |
Enable TLS/SSL | false |
SSL VERIFY |
Verify server certificate | true |
WALLET |
Path to Oracle wallet directory | |
AUTH TYPE |
OS, KERBEROS, or TCPS |
|
DBA PRIVILEGE |
SYSDBA or SYSOPER |
NONE |
LOB FETCH |
pre/inline (default) or post/stream |
pre |
client charset |
Override client-side character set | |
language / territory |
Server message language | |
TRACE FILE |
Enable packet logging | |
proxy client name |
Proxy user schema |
rows, err := db.Query("SELECT id, name, created_at FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var (
id int64
name string
createdAt sql.NullTime
)
if err := rows.Scan(&id, &name, &createdAt); err != nil {
log.Fatal(err)
}
fmt.Println(id, name, createdAt)
}_, err := db.Exec(`CREATE TABLE users (
id NUMBER(10),
name VARCHAR2(50),
created_at DATE
)`)_, err := db.Exec("BEGIN DBMS_LOCK.sleep(5); END;")// Input
_, err := db.Exec("INSERT INTO users (id, name) VALUES (:1, :2)", 1, "Alice")
// Named parameters
_, err := db.Exec("INSERT INTO users (id, name) VALUES (:id, :name)", sql.Named("id", 1), sql.Named("name", "Alice"))
// Output
var name string
_, err = db.Exec("BEGIN SELECT name INTO :1 FROM users WHERE id=:2; END;",
go_ora.Out{Dest: &name, Size: 100}, 1)// Insert
clob := go_ora.Clob{String: "large text value"}
blob := go_ora.Blob{Data: []byte("binary data")}
_, err := db.Exec("INSERT INTO docs (text_col, blob_col) VALUES (:1, :2)", clob, blob)
// Output
var text go_ora.NClob
_, err = db.Exec("BEGIN SELECT text_col INTO :1 FROM docs WHERE id=:2; END;",
go_ora.Out{Dest: &text, Size: 100000}, 1)type User struct {
Id int64 `db:"ID,number"`
Name string `db:"type=varchar,name=NAME"`
}
// Input
_, err := db.Exec("INSERT INTO users (id, name) VALUES (:ID, :NAME)", User{Id: 1, Name: "Alice"})
// Output (requires direction + size)
_, err = db.Exec("BEGIN SELECT id, name INTO :ID, :NAME FROM users WHERE id=:1; END;",
go_ora.Out{Dest: &User{Id: 1}, Size: 100}, 1)CREATE OR REPLACE TYPE address_type AS OBJECT (
street VARCHAR2(100),
city VARCHAR2(50)
);type Address struct {
Street string `udt:"STREET"`
City string `udt:"CITY"`
}
// Register before use
if drv, ok := db.Driver().(*go_ora.OracleDriver); ok {
err := drv.Conn.RegisterType("SCHEMA", "ADDRESS_TYPE", Address{})
}
// Use in queries
var addr Address
rows, err := db.Query("SELECT address_type('123 Main', 'NYC') FROM dual")
rows.Scan(&addr)v, err := go_ora.NewVector([]float32{0.1, 0.2, 0.3})
_, err = db.Exec("INSERT INTO embeddings (id, vec) VALUES (:1, :2)", 1, v)
// Query
var vec go_ora.Vector
rows.Scan(&vec)
data := vec.Data.([]float32) // cast to slicerows, err := db.Query("BEGIN :1 := my_func(:2); END;",
go_ora.Out{Dest: &cursor}, 1)connector, err := go_ora.NewConnector(connStr)
db := sql.OpenDB(connector)config, err := go_ora.ParseConfig(connStr)
config.RegisterDial(func(ctx context.Context, network, address string) (net.Conn, error) {
// custom dialer
})
go_ora.RegisterConnConfig(config)
db, err := sql.Open("oracle", "")err := go_ora.AddSessionParameter(db, "nls_language", "english")
err = go_ora.DelSessionParameter(db, "nls_language")go_ora.SetStringConverter(db, charset, nCharset) // implement IStringConverter| Method | Options |
|---|---|
| Password | Default (user/pass in connection string) |
| OS Auth (Windows) | AUTH TYPE=OS, OS USER, OS PASS, DOMAIN |
| Kerberos5 | AUTH TYPE=KERBEROS + gokrb5 |
| Client Cert | AUTH TYPE=TCPS + SSL=TRUE + WALLET |
| Wallet | wallet=/path/to/cwallet.sso |
| Proxy | proxy client name=schema_owner |
Data encryption (AES) and integrity checking (SHA) are negotiated via Diffie-Hellman key exchange. Configure on the server side in sqlnet.ora:
SQLNET.ENCRYPTION_SERVER = required
SQLNET.ENCRYPTION_TYPES_SERVER = AES256
SQLNET.CRYPTO_CHECKSUM_SERVER = required
SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER = SHA512Control client-side behavior:
urlOptions := map[string]string{
"encryption": "required", // accepted/rejected/required
"data integrity": "required",
}- Pure Go -- no C dependencies or Oracle client required
database/sqlcompatible -- works with standard Go DB pools- Oracle types -- DATE, TIMESTAMP, TIMESTAMP TZ, RAW, LONG, CLOB/BLOB/NCLOB, BFILE
- Advanced types -- Vector (23ai), JSON (23c), BOOLEAN (23c), UDT, nested UDT
- Bulk operations -- insert/merge/update/delete with array parameters
- TLS/SSL -- wallet, mutual TLS, Kerberos5, client certificates
- Encryption -- AES data encryption, SHA data integrity
- Failover -- automatic reconnection on connection loss
- DBMS OUTPUT --
dbms_output.NewOutput(conn, bufferSize) - Multiple result sets -- query returning multiple cursors
- BulkCopy -- Direct Path insert for large datasets
Click to expand full changelog
- Per-session Kerberos auth settings
- Bulk update & delete support
- Bug fixes
- Long input support (up to 1GB for LONG/LOB columns)
RegisterDialfor custom connection dialers
- Multiple result sets
- Connect timeout option
- RefCursor fixes
ParseConfig/RegisterConnConfigAPI- LONG and JSON fixes
- Async connection break
- LOB prefetch returns BLOB as longRAW (up to 1GB)
- Regular type array support
- Nested null object/array support
go_ora.Objectwrapper for UDT parameters
- Nested UDT array support
- Date/time fixes across Oracle versions
- Nested UDT support
- TIME input parameter type resolution
- Valuer/Scanner regressions fixed
- Struct LOB parameters
DelSessionParam
- Most character sets supported
- Buffered network read for slow connections
- Oracle 23c wallet support
time.Time{}as input for DATE/TIMESTAMP
- BFile null value support
- Bulk insert with LOB objects
- Timezone fixes for Oracle 19c
- Session parameter functions
NewDriver/NewConnectorSetStringConverterfor unsupported charsets
WrapRefCursorconverts RefCursor to*sql.Rows
- DBMS_OUTPUT support
- CLOB/BLOB in UDT
- UDT array output parameters
- Global timeout protection
- Empty array/byte fixes
database/sqlfailover viadriver.ErrBadConn- RC4 encryption
- Struct tags for input/output parameters
- Encryption/data integrity URL options
- Bulk insert/merge in ExecContext
- RefCursor mapped to
*sql.Rows
- Named parameters (
sql.Named)
- Client charset option
- Failover re-coded (Query reconnect + re-query)
- Lob prefetch control (
pre/post)
- Client certificate authentication
- BulkCopy using DirectPath (experimental)
- Kerberos5 authentication
- Failover support (reconnect on io.EOF)
- Binary Double/Float fix
- Query to struct
- Proxy user support
- JDBC connect string support
- BFile support
- Unix socket IPC
- Large CLOB/BLOB input
- Connection timeout + context
- Array parameters (associative array)
- BulkInsert
- OS Auth with password hash
- OS Auth (Windows NTS)
- IPv6 support
- Nullable types
- UDT support progression (input, output, arrays, nested)
BuildUrlfor special characters
- TCPS support
- Auto-login wallet
- Data integrity check (SHA)
- AES encryption
- NVarChar type
- TTC v9, 4-byte packet length, advanced negotiation
See examples/ for complete code samples covering CRUD, LOB, UDT, arrays, BulkCopy, RefCursor, and more.