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 urlopen()函数 示例分享
Jun 12 Python
Python用zip函数同时遍历多个迭代器示例详解
Nov 14 Python
python爬虫之urllib库常用方法用法总结大全
Nov 14 Python
Python小白必备的8个最常用的内置函数(推荐)
Apr 03 Python
python操作小程序云数据库实现简单的增删改查功能
Jun 06 Python
Python Django基础二之URL路由系统
Jul 18 Python
python输出带颜色字体实例方法
Sep 01 Python
使用python将最新的测试报告以附件的形式发到指定邮箱
Sep 20 Python
修改Pandas的行或列的名字(重命名)
Dec 18 Python
对tensorflow中tf.nn.conv1d和layers.conv1d的区别详解
Feb 11 Python
python中判断文件结束符的具体方法
Aug 04 Python
解决使用Pandas 读取超过65536行的Excel文件问题
Nov 10 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
模仿OSO的论坛(二)
2006/10/09 PHP
PHP+FLASH实现上传文件进度条相关文件 下载
2007/07/21 PHP
PHP将XML转数组过程详解
2013/11/13 PHP
详解no input file specified 三种解决方法
2019/11/29 PHP
javascript动态改变img的src属性图片不显示的解决方法
2010/10/20 Javascript
js点击页面其它地方将某个显示的DIV隐藏
2012/07/12 Javascript
js实现多选项切换导航菜单的方法
2015/02/06 Javascript
js验证真实姓名与身份证号是否匹配
2015/10/13 Javascript
基于jQuery实现的双11天猫拆红包抽奖效果
2015/12/01 Javascript
JS未跨域操作iframe里的DOM
2016/06/01 Javascript
Bootstrap基本插件学习笔记之模态对话框(16)
2016/12/08 Javascript
详解Angular的双向数据绑定(MV-VM)
2016/12/26 Javascript
javascript修改浏览器title方法 JS动态修改浏览器标题
2017/11/30 Javascript
vue 组件使用中的一些细节点
2018/04/25 Javascript
解决Vue使用swiper动态加载数据,动态轮播数据显示白屏的问题
2018/09/27 Javascript
Python两个整数相除得到浮点数值的方法
2015/03/18 Python
一篇文章入门Python生态系统(Python新手入门指导)
2015/12/11 Python
python logging 日志轮转文件不删除问题的解决方法
2016/08/02 Python
5分钟 Pipenv 上手指南
2018/12/20 Python
解决python有时候import不了当前的包问题
2019/08/28 Python
python中有帮助函数吗
2020/06/19 Python
python用opencv 图像傅里叶变换
2021/01/04 Python
HTML5 canvas画矩形时出现边框样式不一致的解决方法
2013/10/14 HTML / CSS
Joules官网:女士、男士和儿童服装和鞋类
2018/10/23 全球购物
英国礼品和生活方式品牌:Treat Republic
2020/11/21 全球购物
牛津在线药房:Oxford Online Pharmacy
2020/11/16 全球购物
自我评价的正确写法
2013/09/19 职场文书
优秀共产党员演讲稿
2014/09/04 职场文书
2014银行领导班子群众路线对照检查材料思想汇报
2014/09/17 职场文书
2014最新自愿离婚协议书范本
2014/11/19 职场文书
小学六年级班主任工作经验交流材料
2015/11/02 职场文书
2016天猫双十一广告语
2016/01/28 职场文书
高二英语教学反思
2016/03/03 职场文书
python使用tkinter实现透明窗体上绘制随机出现的小球(实例代码)
2021/05/17 Python
GoFrame gredis缓存DoVar Conn连接对象 自动序列化GoFrame gredisDo/DoVar方法Conn连接对象自动序列化/反序列化总结
2022/06/14 Golang
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
2022/08/05 Vue.js