go-oci8

WHACKW · · 7318 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Makhttp://apextips.blogspot.com/2015/09/making-connections-to-oracle-database.htmling connections to the Oracle Database from Gola

I posted the other day about getting going with Golang[1], and as mentioned am planning to do a series of posts on various aspects of the language - as a means to help with the learning process.

Being an Oracle developer, it seemed logical I would want to be able to make connections to the Oracle database. Built into the language core is an SQL interface (for issuing queries and statements) which is through the module "database/sql". The other side of it is that you need a valid driver. A list of available drivers is on the go wiki[2]. You will see that there are 2 listed for Oracle. How do I judge which project to use? First I see that one has considerably more stars and for another, the online commentary I see also seems to suggest that same package. And that is https://github.com/mattn/go-oci8.

Driver setup

Before we get to the driver, you need to make sure you have an Oracle client and the SDK installed on your system. For, this I followed the steps as per the Ubuntu wiki[3] - where you would at minimum want to install the instant client and the SDK. Once the installation is complete, you should end up with an $ORACLE_HOME that points to /usr/lib/oracle/11.2/client64 or something similar depending on your systems architecture and the version of Oracle you installed.

Within $ORACLE_HOME, you should have 3 folders:
  1. bin
  2. include
  3. lib
At this point, if you try to install the aforementioned driver, you will get an error:

$ go get github.com/mattn/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
exit status 1

So, before you install the driver, you need to do the pkg-config set up. This application should be already installed on your system, but if not you can do so with sudo apt-get install pkg-config. This program is just a way to provide the necessary details for compiling and linking a program to a library[4].

The project itself does provide an example of a package config file for oci8, however it's example is for Windows, so the config file I came up with was:

prefixdir=/usr/lib/oracle/11.2/client64
libdir=${prefixdir}/lib
includedir=${prefixdir}/include

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

I just grabbed the path to $ORACLE_HOME and placed it in the variable prefixdir, since the config file doesn't know about environment variables.

Before installing the driver, you need to make this file available in a place that pkg-config knows about. So there are two options here. First, you can place it in the system wide pkg-config directory: /usr/lib/pkgconfig and the system will automatically find it. The other option if you have it some obscure location is to export that location into the environment variable PKG_CONFIG_PATH. Once that is set up, you should be able to successfully install the driver with: go get github.com/mattn/go-oci8

You will now find that both the compiled version and source for that package in your GOPATH (in pkg and src folders respectively).

Connecting and querying database

Now that we have the driver available, we can begin with our program. Most of the aspects I describe here are also documented on the go wiki[5].

First, we want to open our connection. This is done with the sql.Open function[6], where you will pass in the name of the driver, and the connection string.

db, err := sql.Open("oci8", "hr/hr2@example.com:1521/xe")
if err != nil {
    fmt.Println(err)
    return
}
defer db.Close()

Opening the connection is actually deferred until you start issuing statements - so for example, if you enter incorrect password, only when you attempt to query the database will you find out. So in this case, the Ping function[7] might be useful to test the connection is OK.

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

Then, to the actual querying. Here we have the functions Query[8] and QueryRow[9] depending on if you want return a row set or a single row respectively. You will more than likely want to use bind variables in your queries - the documentation suggests the use of `?` as placeholders. And I've also seen examples of `$1`. However, using either of those methods seemed to return the error:

sql: statement expects 0 inputs; got 1

What I've found works is what you would be used to use an Oracle developer - a number prefixed with a colon (:1). I'm assuming that's just the specific implementation of the driver. note: If you repeat the same bind number in your program, don't expect it to be re-used - it's just the position of the bind in the query, and then the respective parameter index. In the result set, you'll then want to declare variables of suitable data types to store the data in, which is fetched with the Scan function.

rows,err := db.Query("select employee_id, first_name from employees where employee_id < :1", 105)
if err != nil {
    fmt.Println("Error fetching employees")
    fmt.Println(err)
    return
}
defer rows.Close()

for rows.Next() {

    var emp_id int
    var first_name string
    rows.Scan(&emp_id, &first_name)
    println(emp_id, first_name)

}

var last_name string
err = db.QueryRow("select last_name from employees where employee_id = :1", 101).Scan(&last_name)
if err != nil {
    fmt.Println("Error fetching row")
    fmt.Println(err)
}

fmt.Printf("Last name is %s\n", last_name)


If you are running a query that doesn't return anything (such as insert or create statements), you would typically use the Exec[10] function. And further, if you are repeating a statement, the Prepare[11] function.

Full program (main.go):

package main

import (
    "fmt"
    "database/sql"
    _ "github.com/mattn/go-oci8"
)

func main(){


    db, err := sql.Open("oci8", "hr/hr@example.com:1521/xe")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer db.Close()
    
    
    if err = db.Ping(); err != nil {
        fmt.Printf("Error connecting to the database: %s\n", err)
        return
    }

    rows,err := db.Query("select employee_id, first_name from employees where employee_id < :1", 105)
    if err != nil {
        fmt.Println("Error fetching employees")
        fmt.Println(err)
        return
    }
    defer rows.Close()

    for rows.Next() {

        var emp_id int
        var first_name string
        rows.Scan(&emp_id, &first_name)
        println(emp_id, first_name)

    }
    
    var last_name string
    err = db.QueryRow("select last_name from employees where employee_id = :1", 101).Scan(&last_name)
    if err != nil {
        fmt.Println("Error fetching row")
        fmt.Println(err)
    }
    
    fmt.Printf("Last name is %s\n", last_name)

}

1: http://tschf.github.io/2015/09/18/getting-going-with-golang/
2: https://github.com/golang/go/wiki/SQLDrivers
3: https://help.ubuntu.com/community/Oracle%20Instant%20Client
4: http://people.freedesktop.org/~dbn/pkg-config-guide.html
5: https://github.com/golang/go/wiki/SQLInterface
6: http://golang.org/pkg/database/sql/#Open
7: http://golang.org/pkg/database/sql/#DB.Ping
8: http://golang.org/pkg/database/sql/#DB.Query
9: http://golang.org/pkg/database/sql/#DB.QueryRow
10: http://golang.org/pkg/database/sql/#DB.Exec
11: http://golang.org/pkg/database/sql/#DB.Prepare


http://apextips.blogspot.com/2015/09/making-connections-to-oracle-database.html

有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:WHACKW

查看原文:go-oci8

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

7318 次点击  
加入收藏 微博
上一篇:RPC和gRPC
下一篇:Vim plugins for Go
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传