安装 链接到标题

安装 oracle 客户端 链接到标题

  • MacOS

由于我的 Mac 没有 oracle 客户端完整版,所以选择安装 oracle 即时客户端,更轻量级。下载地址:Instant Client Downloads for macOS (Intel x86) - Version 19.3.0.0.0 (64-bit),我下载了 Basic Package, SDK Package, SQL*Plus Package 三个包。参考官方安装说明,将三个包解压后放在同一目录,然后设置环境变量如下:

export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/Users/xxx/tools/instantclient_19_3
  • Redhat Linux

由于机器上已安装了 oracle 11.2.0 的客户端,不再安装即时客户端。

安装 c/c++ 链接到标题

一般默认都已安装,跳过

安装 pkg-config 链接到标题

使用 pkg-config –help 可确认是否已安装,如果没有安装,可到官网下载源码编译安装,也可以使用软件包管理工具进行安装。

下载依赖库 go-oci8 链接到标题

go get -v -u github.com/mattn/go-oci8

编写 pkg-config 配置文件 链接到标题

创建一个 oci8.pc 文件,内容如下。注意, prefixdir 为你的 oracle 客户端所在目录

  • MacOS
prefixdir=/Users/xxx/tools/instantclient_19_3
libdir=${prefixdir}
includedir=${prefixdir}/sdk/include

Name: OCI
Description: Oracle database driver
Version: 19.3.0
Libs: -L${libdir} -lclntsh
Cflags: -I${includedir}
  • RedHat Linux
prefixdir=/home/oracle11/app/oracle11/product/11.2.0/dbhome_1
libdir=${prefixdir}
includedir=${prefixdir}/rdbms/public

Name: OCI
Description: Oracle database driver
Version: 11.2.0
Libs: -L${libdir} -lclntsh
Cflags: -I${includedir}

注意,oracle 即时客户端与 oralce 完全版客户端的头文件目录 includedir 不相同。

以上这个文件一般放在 /usr/lib/pkgconfig/ 或者 /usr/local/lib/pkgconfig/ 里,当然也可以放在其它位置,不过这时为了让 pkg-config 可以找到该pc文件,你还要把pc文件所在的路径,添加到环境变量 PKG_CONFIG_PATH 中。

export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/Users/xxx/tools/instantclient_19_3

最后检查 oci8.pc 的正确性,打开新终端,执行 pkg-config –libs –cflags oci8 ,如果输出类似如下,表示配置成功。

-I/Users/xxx/tools/instantclient_19_3/sdk/include -L/Users/xxx/tools/instantclient_19_3 -lclntsh

测试示例 链接到标题

package main

import (
	"database/sql"
	"fmt"
	"log"
	"os"

	_ "github.com/mattn/go-oci8"
)

func main() {
	if len(os.Args) != 2 {
		log.Fatalln(os.Args[0] + " user/password@host:port/sid")
	}

	db, err := sql.Open("oci8", os.Args[1])
	if err != nil {
		log.Fatalln(err)
	}
	defer db.Close()

	err = db.Ping()
	if err != nil {
		fmt.Printf("error connecting to the database: %s\n", err)
		return
	}

	rows, err := db.Query("select t.object_name,t.object_type from user_objects t where t.object_type=:v1", "TABLE")
	if err != nil {
		log.Fatalln(err)
	}
	defer rows.Close()

	for rows.Next() {
		var objectName, objectType string
		rows.Scan(&objectName, &objectType)
		fmt.Printf("object_name=%s,object_type=%s\n", objectName, objectType)
	}
	if err = rows.Err(); err != nil {
		log.Fatalln(err)
	}
}

编译执行

go build .
./oracle_test scott/tiger@192.168.11.22:1521/orcl

参考资料 链接到标题