熱線電話:13121318867

登錄
首頁精彩閱讀Python調用SQLPlus來操作和解析Oracle數據庫的方法
Python調用SQLPlus來操作和解析Oracle數據庫的方法
2018-08-15
收藏

Python調用SQLPlus來操作和解析Oracle數據庫的方法

這篇文章主要介紹了Python調用SQLPlus來操作和解析Oracle數據庫的方法,這樣用SQL*Plus方式來分析Oracle中的數據就變得十分方便,需要的朋友可以參考下

先來看一個簡單的利用python調用sqlplus來輸出結果的例子:    
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,當然最好用cx_Oracle庫,但有時候受到種種限制,不能安裝Python第三方庫,就得利用現有資源,硬著頭皮上了。

用Python調用SqlPlus查詢Oracle,首先要知道SqlPlus返回結果是什么樣的:
    
(這是空行)
Number    Name    Address
------------ ----------- ------------------
1001     張三     南京路
1002     李四     上海路

第1行是空行,第2行是字段名稱,第3行都是橫杠,有空格隔開,第4行開始是查詢到的結果。

在查詢結果規整的情況下,根據第3行可以很清晰的看到結構,用Python解析起來也比較方便。但是,如果一張表字段特別多,記錄數也相當多,那么默認情況下調用SqlPlus查詢出的結果會比較亂,這就需要在調用查詢之前做一些設定,比如:    
set linesize 32767
set pagesize 9999
set term off verify off feedback off tab off
set numwidth 40

這樣的調用查詢結果就比較規整了。接下來就是用強大的Python來解析查詢結果。

這里封裝了一個函數,可以根據傳入的SQL語句查詢并解析結果,將每行結果存到列表中,列表中的每個元素是一個字段名稱與值的映射。    
#!/usr/bin/python
#coding=UTF-8
 
'''
@author: 雙子座@開源中國
@summary: 通過SqlPlus查詢Oracles數據庫
'''
 
import os;
 
os.environ['NLS_LANG'] = 'AMERICAN_AMERICA.AL32UTF8'
gStrConnection = 'username/password@10.123.5.123:1521/ora11g'
 
#解析SqlPlus的查詢結果,返回列表
def parseQueryResult(listQueryResult):
  listResult = []
  #如果少于4行,說明查詢結果為空
  if len(listQueryResult) < 4:
    return listResult
  #第0行是空行,第1行可以獲取字段名稱,第2行可獲取SQLPlus原始結果中每列寬度,第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行開始,解析結果,并建立映射,存儲到列表中
  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
  #構造查詢命令
  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'
  #調用系統命令收集結果
  result = os.popen(strCommand)
  list = []
  for line in result:
    list.append(line)
  return parseQueryResult(list)
其中os.environ['NLS_LANG']的值來自    
select userenv['language'] from dual;
在調用的時候,只要類似:    
listResult = QueryBySqlPlus('select * from studentinfo')
然后就可以用循環打印出結果了。

數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢