golang Oracle数据库SQL操作驱动插件库go-oci8的使用
golang Oracle数据库SQL操作驱动插件库go-oci8的使用
go-oci8简介
Golang Oracle数据库驱动,符合Go database/sql接口规范。
安装步骤
-
安装Oracle完整客户端或Instant Client
-
安装C/C++编译器
-
安装pkg-config,编辑oci8.pc配置文件,然后设置环境变量PKG_CONFIG_PATH指向oci8.pc文件位置 (或者可以使用Go标签noPkgConfig,然后设置环境变量CGO_CFLAGS和CGO_LDFLAGS)
-
使用Go 1.9或更高版本安装:
go get github.com/mattn/go-oci8
oci8.pc配置示例
Windows配置示例
prefix=/devel/target/XXXXXXXXXXXXXXXXXXXXXXXXXX
exec_prefix=${prefix}
libdir=C:/app/instantclient_12_2/sdk/oci/lib/msvc
includedir=C:/app/instantclient_12_2/sdk/include
glib_genmarshal=glib-genmarshal
gobject_query=gobject-query
glib_mkenums=glib-mkenums
Name: oci8
Description: oci8 library
Libs: -L${libdir} -loci
Cflags: -I${includedir}
Version: 12.2
Linux配置示例
prefix=/devel/target/XXXXXXXXXXXXXXXXXXXXXXXXXX
exec_prefix=${prefix}
libdir=/usr/lib/oracle/12.2/client64/lib
includedir=/usr/include/oracle/12.2/client64
glib_genmarshal=glib-genmarshal
gobject_query=gobject-query
glib_mkenums=glib-mkenums
Name: oci8
Description: oci8 library
Libs: -L${libdir} -lclntsh
Cflags: -I${includedir}
Version: 12.2
MacOS配置示例
prefixdir=/Users/<username>/Downloads/instantclient_12_2/
libdir=${prefixdir}
includedir=${prefixdir}/sdk/include
Name: OCI
Description: Oracle database driver
Version: 12.2
Libs: -L${libdir} -lclntsh
Cflags: -I${includedir}
MacOS还需要设置环境变量:
export LD_LIBRARY_PATH=/Users/<username>/Downloads/instantclient_12_2
export PKG_CONFIG_PATH=/Users/<username>/Downloads/instantclient_12_2
使用示例
基本查询示例
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-oci8"
)
func main() {
// 连接Oracle数据库
db, err := sql.Open("oci8", "user/password@host:port/service_name")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 执行查询
rows, err := db.Query("SELECT * FROM employees WHERE employee_id > :1", 100)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
// 处理查询结果
for rows.Next() {
var (
id int
name string
salary float64
)
if err := rows.Scan(&id, &name, &salary); err != nil {
log.Fatal(err)
}
fmt.Printf("ID: %d, Name: %s, Salary: %.2f\n", id, name, salary)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
}
插入数据示例
package main
import (
"database/sql"
"log"
_ "github.com/mattn/go-oci8"
)
func main() {
db, err := sql.Open("oci8", "user/password@host:port/service_name")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 准备插入语句
stmt, err := db.Prepare("INSERT INTO employees (employee_id, name, salary) VALUES (:1, :2, :3)")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
// 执行插入
res, err := stmt.Exec(101, "John Doe", 50000.00)
if err != nil {
log.Fatal(err)
}
// 获取影响行数
rowsAffected, err := res.RowsAffected()
if err != nil {
log.Fatal(err)
}
log.Printf("Inserted %d rows", rowsAffected)
}
事务处理示例
package main
import (
"database/sql"
"log"
_ "github.com/mattn/go-oci8"
)
func main() {
db, err := sql.Open("oci8", "user/password@host:port/service_name")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 开始事务
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
// 执行事务中的操作
_, err = tx.Exec("UPDATE accounts SET balance = balance - 100 WHERE account_id = 1")
if err != nil {
tx.Rollback()
log.Fatal(err)
}
_, err = tx.Exec("UPDATE accounts SET balance = balance + 100 WHERE account_id = 2")
if err != nil {
tx.Rollback()
log.Fatal(err)
}
// 提交事务
err = tx.Commit()
if err != nil {
log.Fatal(err)
}
log.Println("Transaction completed successfully")
}
作者
Yasuhiro Matsumoto (a.k.a mattn)
特别感谢
Jamil Djadala
更多关于golang Oracle数据库SQL操作驱动插件库go-oci8的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang Oracle数据库SQL操作驱动插件库go-oci8的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
go-oci8: Golang Oracle数据库驱动使用指南
go-oci8 是一个用于连接和操作Oracle数据库的Golang驱动。下面我将详细介绍如何使用这个驱动进行Oracle数据库操作。
安装go-oci8
首先需要安装go-oci8驱动:
go get github.com/mattn/go-oci8
系统依赖
go-oci8需要Oracle客户端库(OCI)的支持。在Linux/Unix上需要安装Oracle Instant Client或完整Oracle客户端,在Windows上也需要配置OCI环境。
基本使用示例
1. 连接Oracle数据库
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-oci8"
)
func main() {
// 连接字符串格式: user/password@host:port/sid
// 或者使用TNS名称: user/password@tnsname
db, err := sql.Open("oci8", "scott/tiger@localhost:1521/orcl")
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatal(err)
}
fmt.Println("成功连接到Oracle数据库")
}
2. 执行查询操作
func queryExample(db *sql.DB) {
rows, err := db.Query("SELECT empno, ename, sal FROM emp WHERE deptno = :1", 10)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var empno int
var ename string
var sal float64
err = rows.Scan(&empno, &ename, &sal)
if err != nil {
log.Fatal(err)
}
fmt.Printf("员工号: %d, 姓名: %s, 薪资: %.2f\n", empno, ename, sal)
}
if err = rows.Err(); err != nil {
log.Fatal(err)
}
}
3. 执行插入操作
func insertExample(db *sql.DB) {
// 使用命名参数
result, err := db.Exec(`
INSERT INTO emp (empno, ename, job, sal, deptno)
VALUES (:1, :2, :3, :4, :5)`,
8001, "张三", "程序员", 8500, 10)
if err != nil {
log.Fatal(err)
}
rowsAffected, err := result.RowsAffected()
if err != nil {
log.Fatal(err)
}
fmt.Printf("插入了 %d 行数据\n", rowsAffected)
}
4. 执行事务操作
func transactionExample(db *sql.DB) {
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
// 执行事务中的多个操作
_, err = tx.Exec("UPDATE emp SET sal = sal * 1.1 WHERE deptno = :1", 10)
if err != nil {
tx.Rollback()
log.Fatal(err)
}
_, err = tx.Exec("INSERT INTO emp_audit (action, emp_count, change_date) VALUES ('SAL_UPDATE', 5, SYSDATE)")
if err != nil {
tx.Rollback()
log.Fatal(err)
}
err = tx.Commit()
if err != nil {
log.Fatal(err)
}
fmt.Println("事务执行成功")
}
高级特性
1. 处理CLOB/BLOB类型
func clobExample(db *sql.DB) {
var clobData string
err := db.QueryRow("SELECT resume FROM employees WHERE empno = :1", 7369).Scan(&clobData)
if err != nil {
log.Fatal(err)
}
fmt.Println("CLOB内容:", clobData)
}
func blobExample(db *sql.DB) {
var blobData []byte
err := db.QueryRow("SELECT photo FROM employees WHERE empno = :1", 7369).Scan(&blobData)
if err != nil {
log.Fatal(err)
}
fmt.Println("BLOB数据长度:", len(blobData))
}
2. 调用存储过程
func callProcedure(db *sql.DB) {
// 调用无返回值的存储过程
_, err := db.Exec("BEGIN raise_salary(:1, :2); END;", 7369, 500)
if err != nil {
log.Fatal(err)
}
// 调用有返回值的存储过程
var newSalary float64
err = db.QueryRow(`
BEGIN
get_employee_salary(:1, :2);
END;`,
7369, sql.Out{Dest: &newSalary}).Scan(&newSalary)
if err != nil {
log.Fatal(err)
}
fmt.Printf("新工资: %.2f\n", newSalary)
}
连接池配置
func connectionPoolExample() {
db, err := sql.Open("oci8", "scott/tiger@localhost:1521/orcl")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 设置连接池参数
db.SetMaxOpenConns(10) // 最大打开连接数
db.SetMaxIdleConns(5) // 最大空闲连接数
db.SetConnMaxLifetime(30 * time.Minute) // 连接最大生命周期
// 使用连接池...
}
注意事项
-
OCI环境配置:确保Oracle客户端库正确安装并配置了环境变量(如PATH、LD_LIBRARY_PATH等)
-
字符集问题:Oracle数据库通常使用AL32UTF8字符集,确保应用程序字符集与之匹配
-
日期时间处理:Oracle的DATE类型会被映射为time.Time类型
-
NULL值处理:使用sql.NullString、sql.NullInt64等类型处理可能为NULL的列
-
性能考虑:对于大量数据操作,考虑使用批量插入或数组绑定等技术
go-oci8提供了完整的Oracle数据库访问能力,包括事务、存储过程调用、大对象处理等特性。通过合理配置连接池和优化SQL语句,可以构建高效的Oracle数据库应用。