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提取字典key列表的方法
Jul 11 Python
Django实现组合搜索的方法示例
Jan 23 Python
tensorflow入门之训练简单的神经网络方法
Feb 26 Python
Python button选取本地图片并显示的实例
Jun 13 Python
pyqt实现.ui文件批量转换为对应.py文件脚本
Jun 19 Python
Python Django 封装分页成通用的模块详解
Aug 21 Python
Python实现线性插值和三次样条插值的示例代码
Nov 13 Python
简单介绍django提供的加密算法
Dec 18 Python
Python高阶函数、常用内置函数用法实例分析
Dec 26 Python
使用python求解二次规划的问题
Feb 29 Python
详解Scrapy Redis入门实战
Nov 18 Python
Python 阶乘详解
Oct 05 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下使用SMTP发邮件的代码
2008/01/10 PHP
php发送post请求的三种方法
2014/02/11 PHP
php 过滤英文标点符号及过滤中文标点符号代码
2014/06/12 PHP
php微信公众号开发模式详解
2016/11/28 PHP
JS中confirm,alert,prompt函数使用区别分析
2010/04/01 Javascript
Javascript中的相等与不等运算
2010/04/25 Javascript
jQuery制作仿腾讯web qq用户体验桌面
2013/08/20 Javascript
js hover 定时器(实例代码)
2013/11/12 Javascript
javascript实现修改微信分享的标题内容等
2014/12/11 Javascript
浏览器环境下JavaScript脚本加载与执行探析之动态脚本与Ajax脚本注入
2016/01/19 Javascript
原生JS实现平滑回到顶部组件
2016/03/16 Javascript
jquery获取复选框的值的简单实例
2016/05/26 Javascript
Angular4如何自定义首屏的加载动画详解
2017/07/26 Javascript
JS中关于正则的巧妙操作
2017/08/31 Javascript
Express使用html模板的详细代码
2017/09/18 Javascript
Jquery的Ajax技术使用方法
2019/01/21 jQuery
解决Antd Table表头加Icon和气泡提示的坑
2020/11/17 Javascript
简单的Python的curses库使用教程
2015/04/11 Python
浅谈python 线程池threadpool之实现
2017/11/17 Python
对DJango视图(views)和模版(templates)的使用详解
2019/07/17 Python
Django实现跨域请求过程详解
2019/07/25 Python
pytorch中的上采样以及各种反操作,求逆操作详解
2020/01/03 Python
TensorFlow2.1.0安装过程中setuptools、wrapt等相关错误指南
2020/04/08 Python
pyinstaller将含有多个py文件的python程序做成exe
2020/04/29 Python
python 获取域名到期时间的方法步骤
2021/02/10 Python
巴西葡萄酒商店:Divvino
2020/02/22 全球购物
声明struct x1 { . . . }; 和typedef struct { . . . }x2;有什么不同
2012/06/02 面试题
反邪教宣传工作方案
2014/05/07 职场文书
2014年社区妇联工作总结
2014/12/02 职场文书
英语感谢信范文
2015/01/20 职场文书
优秀教师工作总结2015
2015/07/22 职场文书
公司中层管理培训心得体会
2016/01/11 职场文书
英文诗歌翻译方法(赏析)
2019/08/16 职场文书
解析高可用Redis服务架构分析与搭建方案
2021/06/20 Redis
canvas实现贪食蛇的实践
2022/02/15 Javascript
Python 视频画质增强
2022/04/28 Python