Python調(diào)用SQLPlus來(lái)操作和解析Oracle數(shù)據(jù)庫(kù)的方法
先來(lái)看一個(gè)簡(jiǎn)單的利用python調(diào)用sqlplus來(lái)輸出結(jié)果的例子:
import os import sys from subprocess import Popen, PIPE sql = """ set linesize 400 col owner for a10 col object_name for a30 select owner, object_name from dba_objects where rownum<=10; """ proc = Popen(["sqlplus", "-S", "/", "as", "sysdba"], stdout=PIPE, stdin=PIPE, stderr=PIPE) proc.stdin.write(sql) (out, err) = proc.communicate() if proc.returncode != 0: print err sys.exit(proc.returncode) else: print out
用Python查詢Oracle,當(dāng)然最好用cx_Oracle庫(kù),但有時(shí)候受到種種限制,不能安裝Python第三方庫(kù),就得利用現(xiàn)有資源,硬著頭皮上了。
用Python調(diào)用SqlPlus查詢Oracle,首先要知道SqlPlus返回結(jié)果是什么樣的:
(這是空行) Number Name Address ------------ ----------- ------------------ 1001 張三 南京路 1002 李四 上海路
第1行是空行,第2行是字段名稱,第3行都是橫杠,有空格隔開,第4行開始是查詢到的結(jié)果。
在查詢結(jié)果規(guī)整的情況下,根據(jù)第3行可以很清晰的看到結(jié)構(gòu),用Python解析起來(lái)也比較方便。但是,如果一張表字段特別多,記錄數(shù)也相當(dāng)多,那么默認(rèn)情況下調(diào)用SqlPlus查詢出的結(jié)果會(huì)比較亂,這就需要在調(diào)用查詢之前做一些設(shè)定,比如:
set linesize 32767 set pagesize 9999 set term off verify off feedback off tab off set numwidth 40
這樣的調(diào)用查詢結(jié)果就比較規(guī)整了。接下來(lái)就是用強(qiáng)大的Python來(lái)解析查詢結(jié)果。
這里封裝了一個(gè)函數(shù),可以根據(jù)傳入的SQL語(yǔ)句查詢并解析結(jié)果,將每行結(jié)果存到列表中,列表中的每個(gè)元素是一個(gè)字段名稱與值的映射。
#!/usr/bin/python #coding=UTF-8 ''' @author: 雙子座@開源中國(guó) @summary: 通過SqlPlus查詢Oracles數(shù)據(jù)庫(kù) ''' import os; os.environ['NLS_LANG'] = 'AMERICAN_AMERICA.AL32UTF8' gStrConnection = 'username/password@10.123.5.123:1521/ora11g' #解析SqlPlus的查詢結(jié)果,返回列表 def parseQueryResult(listQueryResult): listResult = [] #如果少于4行,說(shuō)明查詢結(jié)果為空 if len(listQueryResult) < 4: return listResult #第0行是空行,第1行可以獲取字段名稱,第2行可獲取SQLPlus原始結(jié)果中每列寬度,第3行開始是真正輸出 # 1 解析第2行,取得每列寬度,放在列表中 listStrTmp = listQueryResult[2].split(' ') listIntWidth = [] for oneStr in listStrTmp: listIntWidth.append(len(oneStr)) # 2 解析第1行,取得字段名稱放在列表中 listStrFieldName = [] iLastIndex = 0 lineFieldNames = listQueryResult[1] for iWidth in listIntWidth: #截取[iLastIndex, iLastIndex+iWidth)之間的字符串 strFieldName = lineFieldNames[iLastIndex:iLastIndex + iWidth] strFieldName = strFieldName.strip() #去除兩端空白符 listStrFieldName.append(strFieldName) iLastIndex = iLastIndex + iWidth + 1 # 3 第3行開始,解析結(jié)果,并建立映射,存儲(chǔ)到列表中 for i in range(3, len(listQueryResult)): oneLiseResult = unicode(listQueryResult[i], 'UTF-8') fieldMap = {} iLastIndex = 0 for j in range(len(listIntWidth)): strFieldValue = oneLiseResult[iLastIndex:iLastIndex + listIntWidth[j]] strFieldValue = strFieldValue.strip() fieldMap[listStrFieldName[j]] = strFieldValue iLastIndex = iLastIndex + listIntWidth[j] + 1 listResult.append(fieldMap) return listResult def QueryBySqlPlus(sqlCommand): global gStrConnection #構(gòu)造查詢命令 strCommand = 'sqlplus -S %s <<!\n' % gStrConnection strCommand = strCommand + 'set linesize 32767\n' strCommand = strCommand + 'set pagesize 9999\n' strCommand = strCommand + 'set term off verify off feedback off tab off \n' strCommand = strCommand + 'set numwidth 40\n' strCommand = strCommand + sqlCommand + '\n' #調(diào)用系統(tǒng)命令收集結(jié)果 result = os.popen(strCommand) list = [] for line in result: list.append(line) return parseQueryResult(list)
其中os.environ['NLS_LANG']的值來(lái)自
select userenv['language'] from dual;
listResult = QueryBySqlPlus('select * from studentinfo')
然后就可以用循環(huán)打印出結(jié)果了。
- python使用 cx_Oracle 模塊進(jìn)行查詢操作示例
- python連接oracle數(shù)據(jù)庫(kù)實(shí)例
- python cx_Oracle的基礎(chǔ)使用方法(連接和增刪改查)
- Python使用cx_Oracle模塊操作Oracle數(shù)據(jù)庫(kù)詳解
- python cx_Oracle模塊的安裝和使用詳細(xì)介紹
- Python導(dǎo)入oracle數(shù)據(jù)的方法
- Python3.6連接Oracle數(shù)據(jù)庫(kù)的方法詳解
- python安裝cx_Oracle模塊常見問題與解決方法
- Python使用cx_Oracle模塊將oracle中數(shù)據(jù)導(dǎo)出到csv文件的方法
- python實(shí)現(xiàn)Oracle查詢分組的方法示例
相關(guān)文章
python爬蟲實(shí)現(xiàn)最新12306搶票
這篇文章主要介紹了python爬蟲實(shí)現(xiàn)最新12306搶票,每到放假過節(jié)的時(shí)候,很多人總是對(duì)于搶不到車票而煩惱,那么經(jīng)過我?guī)讉€(gè)小時(shí)的不懈努力,完成了基于python?的12306搶票爬蟲,現(xiàn)在分享給大家。希望對(duì)大家有所幫助2022-01-01關(guān)于Python中的向量相加和numpy中的向量相加效率對(duì)比
今天小編就為大家分享一篇關(guān)于Python中的向量相加和numpy中的向量相加效率對(duì)比,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2019-08-08Python 處理表格進(jìn)行成績(jī)排序的操作代碼
這篇文章主要介紹了Python 處理表格進(jìn)行成績(jī)排序,也就是說(shuō)將學(xué)生從按照學(xué)號(hào)排序變?yōu)榘凑粘煽?jī)從高到低進(jìn)行排序,具體實(shí)現(xiàn)代碼跟隨小編一起看看吧2021-07-07jupyter notebook保存文件默認(rèn)路徑更改方法匯總(親測(cè)可以)
安裝Anaconda后,新建文件的默認(rèn)存儲(chǔ)路徑一般在C系統(tǒng)盤,那么路徑是什么呢?如何更改jupyter notebook保存文件默認(rèn)路徑呢?今天小編就這一問題通過兩種方法給大家講解,需要的朋友跟隨小編一起看看吧2021-06-06對(duì)numpy數(shù)據(jù)寫入文件的方法講解
今天小編就為大家分享一篇對(duì)numpy數(shù)據(jù)寫入文件的方法講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2018-07-07Python?中如何將十六進(jìn)制轉(zhuǎn)換為?Base64
本篇文章將介紹在?Python?中將?hex?轉(zhuǎn)換為?base64?的方法,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06