本文在 Windows 7 64bit 系统上使用 golang 连接查询 oracle 数据库。

环境准备

前置条件:
安装mingw(取其gcc及库,因为要用cgo编译),安装git(取其bash)。安装oci。

oracle提供了编程接口,golang 有多个实现库,但均需依赖 oracle 的 instantclient。下载OCI:
https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html 。
版本有 SDK 版本、Basic 版本。压缩包虽不同,但内含目录一致,解压到当前目录即可,拷贝到指定目录,示例:D:\oracle\instantclient

PKG_CONFIG_PATH环境变量 (失败)

D:\mingw64\lib\pkg-config

执行echo $PKG_CONFIG_PATH查看目录,映射到 E:\Program Files\Git\mingw64\lib 下,不存在pkgconfig,创建之。

安装库

1、
获取oci8.pc。执行:

go get github.com/wendal/go-oci8
提示:
# pkg-config --cflags  -- oci8
Package oci8 was not found in the pkg-config search path.
Perhaps you should add the directory containing `oci8.pc'
to the PKG_CONFIG_PATH environment variable
No package 'oci8' found

无须理会错误,此处是下载源码,主要获取pkg-config.exe和oci8.pc文件。在下载包go-oci8的windows目录,将pkg-config.exe拷贝到git的bin目录,oci8.pc拷贝到 E:\Program Files\Git\mingw64\lib\pkgconfig 目录。

2、
再次执行:

go get github.com/wendal/go-oci8
提示:
# github.com/wendal/go-oci8
D:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lclntsh
collect2.exe: error: ld returned 1 exit status

一说:把oci8.pc文件的lclntsh改为oci,修改后,再执行,通过。得到pkg\windows_amd64\github.com\wendal\go-oci8.a目录。

由作者说明得知,wendal是从mattn仓库fork得到的,也下载:

go get github.com/mattn/go-oci8

对比两者源码和生成的.a文件,mattn的文件也多,库也比较大。但对比使用者而言无区别。为安全起见,实际工程使用 mattn 库。

3、
oci8.pc内容:

#prefix=D:/oracle/instantclient
includedir=D:/oracle/instantclient/sdk/include
libdir=D:/oracle/instantclient/sdk/lib/msvcName: oci8
Description: Oracle Instant Client
Version: 19.8
Cflags: -I${includedir}
Libs: -L${libdir} -loci

注:使用全路径,不使用prefix(因为git安装的目录带有空格),将库修改为oci。

4、
编写测试代码。go build 出错:

# command-line-arguments
D:\go\pkg\tool\windows_amd64\link.exe: running gcc failed: exit status 1
D:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -loci
collect2.exe: error: ld returned 1 exit status

猜想:官方oci是.lib格式,gcc不认。而golang的驱动得到.a但没有包括oci里面的函数。将得到的go-oci8.a改名为liboci.a,再次go build,提示未定义的函数,用nm查之,函数前为U,猜测格式不对。

$ pkg-config --cflags -- oci8
-ID:/oracle/instantclient/sdk/include

D:\oracle\instantclient目录找oci.dll,放到临时目录。从dll生成.a。

$ gendef.exe oci.dll  # 注:从dll生产def(下一步要用到)* [oci.dll] Found PE image$ dlltool.exe -D oci.dll -d oci.def -l liboci.a # 从dll和def生成.a文件。

生成的文件为liboci.a,可用nm查函数,已有定义。将其放到mingw的lib目录(这样就不用再额外设置路径),本文为 D:\mingw64\lib 。

5、
疑惑1:
似乎golang生成的go-oci8.a没什么用,可能内部链接了里面的函数,但最终的oci函数,还是从官方的oci库中获取,如OCIStmtPrepare。
疑惑2:
go get github.com/mattn/go-oci8处,会使用pc文件指定的参数,但似乎只针对头文件,也没有链接,具体未详细研究(因为.lib和.a格式已然不同,不通用,链接不上的,没报错,应该没链接)。

源码

package mainimport ("database/sql""log""errors"// 导入mysql驱动_ "github.com/mattn/go-oci8"
)func CreateOracle(dbstr string) (sqldb *sql.DB, err error) {sqldb, err = sql.Open("oci8", dbstr)if err != nil {return nil, errors.New("open database failed: " + err.Error())}err = sqldb.Ping()if err != nil {return nil, errors.New("connect database failed: " + err.Error())}log.Println("connect to oracle ok")//log.Println("connect to ", dbParam.server, dbParam.database, "ok")return
}func GetVersion(sqldb *sql.DB) () {// 降序,最新的在前面results, err := sqldb.Query("select version, codetype, addtime from tablevesion order by tablevesion desc")if err != nil {fmt.Println("Query error: ", err)return}for results.Next() {var item1, item2, item3 sql.NullStringerr := results.Scan(&item1, &item2, &item3)if err != nil {fmt.Println("scan error: ", err)break}if (!item1.Valid || !item2.Valid || !item3.Valid) {continue}fmt.Println(item1.String, item2.String, item3.String)}return
}var dbstr = "latelee/123456789@192.168.18.188:1521/mydb"
func main() {fmt.Println("oracle test")SQLDB, err := CreateOracle(dbstr)if err != nil {fmt.Println("open db failed", err)return}GetVersion(SQLDB)
}

参考资料

参考资料:
https://www.cnblogs.com/good-temper/p/3791874.html
https://blog.csdn.net/yh_coco/article/details/78068610

Golang实践录:oracle数据库实践相关推荐

  1. oracle数据库实践周总结,「Oracle实践数据库」总结

    关于老师 这个老师的讲课节奏其实挺快的,后边听课的时候我也在想,大概东西/知识掌握的很熟练的人,对于这样的讲解基本上就是这样子快了,不过苦了我们学生..大概认真听课到跟上老师节奏花费了我两三周的时间, ...

  2. oracle数据库实践,RubyonRails连接Oracle数据库实践

    今天学习了一下最近流行的Ruby on Rails,感觉:就是一个代码生成器 链接Oracle数据库的时候,查了半天的资料.终于找到办法了,^______^ 1.安装驱动 下载并运行(双击)ruby- ...

  3. ORACLE数据库中使用JAVA源实现SM3签名算法

    目    录 ORACLE数据库中使用JAVA源实现SM3签名算法... 1 1.          JAVA源简介.. 4 2.          JAVA源实现SM3签名... 4 3.      ...

  4. oracle数据库如何写翻页_ORACLE数据库分页查询/翻页 最佳实践

    ORACLE数据库分页查询/翻页 最佳实践 一.示例数据: Select Count(*) From dba_objects ; ----------------------------------- ...

  5. oracle数据库----SQL语句的实践(应用实例)

    oracle数据库----SQL语句的实践(应用实例) 创建表工资表salary,包括员工号emp_id,员工名emp_name,员工月基本工资monthsal,员工月总发工资totalsal. cr ...

  6. 嘉年华回顾丨 樊文凯分享Oracle 数据库异构上云最佳实践

    2020年数据技术嘉年华还有一周多的时间,相信大家期待值也越来越高.数据技术嘉年华组委会在此精心为大家准备了"嘉年华回顾",挑选往届大会中热门的演讲.小编带大家回顾往届的高光时刻! ...

  7. 文档丨Oracle数据库异构上云最佳实践

    墨天轮文档:<Oracle数据库异构上云最佳实践-唐修>:https://www.modb.pro/doc/1301(复制到浏览器中打开或者点击"阅读原文"立即下载) ...

  8. 动手为王 | Oracle 数据库跨版本升级迁移实践

    作者简介 李真旭 Oracle ACE 专家,拥有超过10年的 Oracle 运维管理使用经验,参与过众多移动.电信.联通.银行等大型数据库交付项目,具有丰富的运维管理经验,对 Oracle 数据库管 ...

  9. Golang实践录:命令行cobra库实例再三优化

    本文是上一文章<Golang实践录:命令行cobra库实例优化> 的优化,主要的子命令的业务实现的整理. 起因 上一版本实现的方式,还是有点不满意,格式也不对齐,重要的是,似乎不是正规的方 ...

最新文章

  1. python get请求 由于目标机器_使用python和selenium进行Web抓取:由于目标机器主动拒绝i...
  2. optee应用程序中malloc函数的原理介绍
  3. 《编码的奥秘》---学习编程一年半的体会
  4. C#Windows 服务制作安装删除. 用户注销后,程序继续运行 (转载)
  5. boost::make_biconnected_planar用法的测试程序
  6. Map集合中的一些具体方法的体现
  7. 【简洁+注释】剑指 Offer 32 - II. 从上到下打印二叉树 II
  8. mysql导出数据字典6_MySQL利用Navicat导出数据字典
  9. C++自动类型推导 : auto 与 decltype 用法
  10. const 常量_条款03:尽可能使用const
  11. html中css如何引用自定义字体 - 案例篇
  12. 从入门到入土:Nessus出击:使用nessus扫描某台靶机
  13. PHP SQL查询结果在页面上是乱码
  14. Windows驱动开发,几个BLOG值得经常看看
  15. Fastlane基础介绍
  16. 【运动学】基于matlab计步【含Matlab源码 524期】
  17. Ubuntu 18.04中安装飞行模拟器FlightGear 2018.2.1
  18. ccfb类会议有哪些_CCF推荐的国际学术会议和期刊目录修订版发布
  19. html怎么隐藏音频的图标,XP系统realtek高清晰音频管理器图标如何隐藏
  20. Linux ruby离线安装

热门文章

  1. MFC开发IM-第十九篇、获取编辑框内容,并且追加内容
  2. 假如啤酒只有七天生命
  3. 原好未来CFO罗戎加盟百度 出任百度集团CFO
  4. 拜登将主持商讨网络安全问题,苹果和微软CEO参加
  5. 中国恒大:正接触独立第三方投资者
  6. 漯河首富,一年杀猪5000万头
  7. 小米11新旗舰通过3C认证:支持最高67.1W快充
  8. 曝张一鸣在游戏群批员工上班时聊游戏,遭回怼:那你退群啊
  9. 征集“战疫”中的影像力量 第六届中国无人机影像大赛开始报名
  10. 小米40W无线闪充今年商用:MIX 4首发?