Python调用SQLPlus来操作和解析Oracle数据库的方法


Posted in Python onApril 09, 2016

先来看一个简单的利用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')

然后就可以用循环打印出结果了。

Python 相关文章推荐
python处理cookie详解
Feb 07 Python
Python常用随机数与随机字符串方法实例
Apr 09 Python
Python操作MongoDB数据库PyMongo库使用方法
Apr 27 Python
关于pip的安装,更新,卸载模块以及使用方法(详解)
May 19 Python
NumPy 如何生成多维数组的方法
Feb 05 Python
python读取各种文件数据方法解析
Dec 29 Python
使用Python实现毫秒级抢单功能
Jun 06 Python
Python中的pathlib.Path为什么不继承str详解
Jun 23 Python
python实现函数极小值
Jul 10 Python
Python 3 判断2个字典相同
Aug 06 Python
Python线程协作threading.Condition实现过程解析
Mar 12 Python
通过代码实例了解Python sys模块
Sep 14 Python
python调用fortran模块
Apr 08 #Python
python3使用urllib模块制作网络爬虫
Apr 08 #Python
Python抓取电影天堂电影信息的代码
Apr 07 #Python
Python Requests安装与简单运用
Apr 07 #Python
Python Requests 基础入门
Apr 07 #Python
Python检测网站链接是否已存在
Apr 07 #Python
python多进程共享变量
Apr 06 #Python
You might like
php split汉字
2009/06/05 PHP
在SAE上搭建最新wordpress的方法
2014/12/21 PHP
php中输出json对象的值(实现方法)
2018/03/07 PHP
js调用flash的效果代码
2008/04/26 Javascript
Document 对象的常用方法
2009/07/31 Javascript
利用javascript的面向对象的特性实现限制试用期
2011/08/04 Javascript
jquery动画3.创建一个带遮罩效果的图片走廊
2012/08/24 Javascript
jQuery插件实现控制网页元素动态居中显示
2015/03/24 Javascript
七夕情人节丘比特射箭小游戏
2015/08/20 Javascript
浅谈JavaScript的全局变量与局部变量
2016/06/10 Javascript
JS多物体实现缓冲运动效果示例
2016/12/20 Javascript
JSON字符串和JSON对象相互转化实例详解
2017/01/05 Javascript
完美解决node.js中使用https请求报CERT_UNTRUSTED的问题
2017/01/08 Javascript
javascript 单例模式详解及简单实例
2017/02/14 Javascript
Angular指令之restict匹配模式的详解
2017/07/27 Javascript
深入浅析javascript继承体系
2017/10/23 Javascript
JavaScript数组去重算法实例小结
2018/05/07 Javascript
angularJS1 url中携带参数的获取方法
2018/10/09 Javascript
JavaScript基于面向对象实现的无缝滚动轮播示例
2020/01/17 Javascript
ant design vue嵌套表格及表格内部编辑的用法说明
2020/10/28 Javascript
[02:04]2018DOTA2亚洲邀请赛Secret赛前采访
2018/04/03 DOTA
Python正则表达式完全指南
2017/05/25 Python
使用Python爬了4400条淘宝商品数据,竟发现了这些“潜规则”
2018/03/23 Python
使用python读取csv文件快速插入数据库的实例
2018/06/21 Python
pytorch .detach() .detach_() 和 .data用于切断反向传播的实现
2019/12/27 Python
对tensorflow 中tile函数的使用详解
2020/02/07 Python
python 第三方库paramiko的常用方式
2021/02/20 Python
Html5 postMessage实现跨域消息传递
2016/03/11 HTML / CSS
德国高性价比网上药店:medpex
2017/07/09 全球购物
经济管理专业毕业生推荐信
2013/11/11 职场文书
党校培训思想汇报
2013/12/30 职场文书
好书伴我成长演讲稿
2014/05/14 职场文书
计算机应用应届生求职信
2014/07/12 职场文书
2016年基层党组织创先争优承诺书
2016/03/25 职场文书
修改并编译golang源码的操作步骤
2021/07/25 Golang
游戏《铁拳》动画化!2022年年内播出
2022/03/21 日漫