lua連接oracle解決方法與步驟

測試環境centos7html

1) 使用luajit ,這個比較簡單,下載luajit源碼,編譯便可mysql

    省略linux

如下是具體操做步驟:git

參考文章:http://www.programgo.com/article/15452439520/github

可是步驟寫的有點快,很難解決問題,因此從新來搞一下:sql

 

2) 下載luasql,數據庫

   git clone https://github.com/keplerproject/luasql.givim

3) 編譯make odbccentos

須要修改源代碼目錄中的config文件oracle

調整lua相關的路徑

LUA_LIBDIR =

LUA_DIC = /usr/local/bin/luajit-2.0.4

LUA_INC = /usr/local/include/luajit-2.0/

        make odbc,提示找不到sql.h文件

        須要安裝unixODBC

        yum install unixODBC unixODBC-devel -y

 

       編譯以後,執行make install

       odbc.so文件被複制到/luasql目錄中

 

4) 須要編譯oci8

make oci8   須要oracle中的開發包,

A: 須要下載:

     版本號須要對應一下,下載連接地址,請移步: 須要登陸

     http://www.oracle.com/technetwork/cn/topics/linuxx86-64soft-092277.html

          oracle-instantclient-basic-10.2.0.4-1.i386.zip 

          oracle-instantclient-devel-10.2.0.4-1.i386.zip     //這個是sdk 的,文件名上沒有說明,特此說明 

          oracle-instantclient-sqlplus-10.2.0.4-1.i386.zip  (注意版本號) 

         1) base,2)devel 3) sqlplus ,下載rpm包  使用 rpm -ivh xxx.rpm來安裝(注意下載與系統符合的x64)

B: 修復config文件修改

         本人測試使用的是oracle-instantclient12.1-sqlplus-12.1.0.1.0-1.x86_64.rpm

        DRIVER_LIBS_oci8 ?= -L/usr/lib/oracle/12.1/client64/lib/ -lclntshcore -lclntsh -lipc1 -lmql1 -lnnz12 -locci -lociei -locijdbc12 -lons -loramysql12 -lsqlplusic -lsqlplus ###注意標色的,否則會出現下面的錯誤

         DRIVER_INCS_oci8 ?= -I/usr/include/oracle/12.1/client64/

         備註上面的路徑爲默認的安裝路徑,請對應好本身的路徑

須要將oracle的so作連接,放到lib64下面,否則即便編譯成功,lua庫找不到,

ln -s /usr/lib/oracle/12.1/client64/lib/libclntsh.so.12.1 /lib64/libclntsh.so.12.1

ln -s /usr/lib/oracle/12.1/client64/lib/libipc1.so /lib64/libipc1.so

ln -s /usr/lib/oracle/12.1/client64/lib/libmql1.so /lib64/libmql1.so

ln -s /usr/lib/oracle/12.1/client64/lib/libnnz12.so /lib64/libnnz12.so

ln -s /usr/lib/oracle/12.1/client64/lib/libocci.so.12.1 /lib64/libocci.so.12.1

ln -s /usr/lib/oracle/12.1/client64/lib/libociei.so /lib64/libociei.so

ln -s /usr/lib/oracle/12.1/client64/lib/libocijdbc12.so /lib64/libocijdbc12.so

ln -s /usr/lib/oracle/12.1/client64/lib/libons.so /lib64/libons.so

ln -s /usr/lib/oracle/12.1/client64/lib/liboramysql12.so /lib64/liboramysql12.so

ln -s /usr/lib/oracle/12.1/client64/lib/libsqlplusic.so /lib64/libsqlplusic.so

ln -s /usr/lib/oracle/12.1/client64/lib/libsqlplus.so /lib64/libsqlplus.so

ln -s /usr/lib/oracle/12.1/client64/lib/libclntshcore.so.12.1 /lib64/libclntshcore.so.12.1

若是有缺乏,繼續添加.

make clean一下,而後從新生成

make oci8

make odbc

將生成的so文件存放到luasql目錄裏面.

代碼分佈以下

---

├── luasql

│   ├── oci8.so

│   └── odbc.so

└── test.lua

 

------------

test.lua文件內容以下

local driver = require "luasql.oci8"

print(driver)

local env = driver.oci8()

print(env)

local dbcon = assert (env:connect("10.10.10.1", "xxx", "sss"))

print( dbcon )

--------------執行結果:

table: 0x41984530
Oracle environment (0x41984910)
luajit: test.lua:11: LuaSQL: ORA-12504: TNS:listener was not given the SERVICE_NAME in CONNECT_DATA

stack traceback:
        [C]: in function 'assert'
        test.lua:11: in main chunk
        [C]: at 0x00404ac0

好像提示是有個配置文件不對了.目前至少driver和env能打印出對象出來

---------------------------------------------------------------

錯誤彙總:

若是出現符號連接找不到:

luajit test.lua

luajit: error loading module 'luasql.oci8' from file './luasql/oci8.so':

./luasql/oci8.so: undefined symbol: OCIAttrSet

stack traceback:

[C]: at 0x0044b8b0

[C]: in function 'require'

test.lua:1: in main chunk

[C]: at 0x00404ac0

說明編譯參數有問題,沒有連接到庫,對應gcc的參數爲-l 小寫字母l

可使用nm來證實:

ldd -r libluasql_oci8D.so

undefined symbol: lua_settop (./libluasql_oci8D.so)

undefined symbol: OCIAttrSet (./libluasql_oci8D.so)

undefined symbol: lua_toboolean (./libluasql_oci8D.so)

undefined symbol: OCIStmtFetch (./libluasql_oci8D.so)

undefined symbol: OCIDescriptorAlloc (./libluasql_oci8D.so)

undefined symbol: lua_touserdata (./libluasql_oci8D.so)

undefined symbol: luaL_argerror (./libluasql_oci8D.so)

undefined symbol: lua_pushcclosure ( linux-vdso.so.1 => (0x00007fff993b6000)

libc.so.6 => /lib64/libc.so.6 (0x00007f67ab564000)

/lib64/ld-linux-x86-64.so.2 (0x00007f67abb3c000)

./libluasql_oci8D.so)

undefined symbol: lua_tolstring (./libluasql_oci8D.so)

undefined symbol: OCIDescriptorFree (./libluasql_oci8D.so)

undefined symbol: luaL_ref (./libluasql_oci8D.so)

undefined symbol: lua_createtable (./libluasql_oci8D.so)

undefined symbol: lua_rawset (./libluasql_oci8D.so)

undefined symbol: OCIStmtPrepare (./libluasql_oci8D.so)

undefined symbol: luaL_optlstring (./libluasql_oci8D.so)

undefined symbol: OCILobGetLength (./libluasql_oci8D.so)

undefined symbol: OCITransCommit (./libluasql_oci8D.so)

一看到undefined symbol,你懂的.

 

so文件找不到,路徑不正確:

luajit: error loading module 'luasql.oci8' from file './luasql/oci8.so':

libclntshcore.so.12.1: cannot open shared object file: No such file or directory

stack traceback:

[C]: at 0x0044b8b0

[C]: in function 'require'

test.lua:1: in main chunk

[C]: at 0x00404ac0

說明對應的so文件,沒有在默認的系統環境變量裏面

使用上面的ln -s作軟連接便可,

把缺的文件所有加上

 

 

=====================繼續解決上面lua鏈接報錯

ORA-12504: TNS:listener was not given the SERVICE_NAME in CONNECT_DATA

 

1) 安裝oracle-instantclient12.1-odbc-12.1.0.2.0-1.x86_64.rpm

2) 請檢查是否存在目錄/home/oracle

文件內容以下:

cat /home/oracle/network/admin/tnsnames.ora 
UAT_DB =  #注意這個地方的UAT_DB,一會要在ini中用到
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.100.1.1)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = uat)
    )
  )

而後配置unixODBC,用來測試

注意文件:

 cat /etc/odbcinst.ini 
# Example driver definitions

# Driver from the postgresql-odbc package
# Setup from the unixODBC package
[PostgreSQL]
Description     = ODBC for PostgreSQL
Driver          = /usr/lib/psqlodbcw.so
Setup           = /usr/lib/libodbcpsqlS.so
Driver64        = /usr/lib64/psqlodbcw.so
Setup64         = /usr/lib64/libodbcpsqlS.so
FileUsage       = 1


# Driver from the mysql-connector-odbc package
# Setup from the unixODBC package
[MySQL]
Description     = ODBC for MySQL
Driver          = /usr/lib/libmyodbc5.so
Setup           = /usr/lib/libodbcmyS.so
Driver64        = /usr/lib64/libmyodbc5.so
Setup64         = /usr/lib64/libodbcmyS.so
FileUsage       = 1


[Oracle]
Description     = Oracle ODBC driver for Oracle 11g
Driver      = /usr/lib/oracle/12.1/client64/lib/libsqora.so.12.1 #文件根據安裝odbc的rpm版本對應
Setup           =
FileUsage       =
CPTimeout       =
CPReuse         = 

 

配置odbc.ini文件

cat /etc/odbc.ini 
[OracleODBC]  #這個名稱是給isql用的
Application Attributes = T
Attributes = W
BatchAutocommitMode = IfAllSuccessful
BindAsFLOAT = F
CloseCursor = F
DisableDPM = F
DisableMTS = T
Driver = Oracle 
DSN = OracleODBC
EXECSchemaOpt =
EXECSyntax = T
Failover = T
FailoverDelay = 10
FailoverRetryCount = 10
FetchBufferSize = 64000
ForceWCHAR = F
Lobs = T
Longs = T
MetadataIdDefault = F
QueryTimeout = T
ResultSets = T
ServerName = UAT_DB ##對應oca文件中的名稱
SQLGetData extensions = F
Translation DLL =
Translation ption = 0
DisableRULEHint = T
UserID =

該ini文件,須要找到UAT_DB,也就是須要找到ora文件,須要設置2個環境變量

vim /etc/profile

添加

export ORACLE_HOME=/home/oracle/
export TNS_ADMIN=/home/oracle/network/admin

使用source /etc/profile命令生效

使用isql來測試一下

用法isql OracleODBC user password -v

[root@host admin]# isql OracleODBC user passwrod -v 
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> select count(*) from account;
+-----------------------------------------+
| COUNT(*)                                |
+-----------------------------------------+
| 21                                   |
+-----------------------------------------+
SQLRowCount returns -1
1 rows fetched

說明遊戲,

 

開始使用腳原本測試

test.lua文件內容:

[root@host luaoracle]# cat test.lua 
local driver = require "luasql.oci8"
print(driver)

local env = driver.oci8()
print(env)

---- 注意第一個參數爲oca中的名稱,後面是用戶名,密碼
local dbcon = assert (env:connect("UAT_DB", "username", "password"))
print( dbcon )

local sql = "select count(1) as c from account"
local cursor = dbcon:execute(sql)  ---- 執行一個sql語句,簡單的,值統計表裏有多少行
print(cursor)  ----返回的是一個cursor,

local ret = cursor:fetch({},"a")  ---- 取出cursor中的數據,
for k , v in pairs(ret) do
   print(string.format("%s %s",k , v ))
end

執行一下試試

[root@host luaoracle]# luajit test.lua 
table: 0x41f7c8a8
Oracle environment (0x41f7cc88)
Oracle connection (0x41f7ccf8)
Oracle cursor (0x41f7c090)
c 21

key:c

value: 21

表示數據庫中返回的字段與值

相關文章
相關標籤/搜索