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连接mysql调用存储过程示例
Mar 05 Python
python实现根据用户输入从电影网站获取影片信息的方法
Apr 07 Python
仅用50行Python代码实现一个简单的代理服务器
Apr 08 Python
Django中使用locals()函数的技巧
Jul 16 Python
python脚本监控docker容器
Apr 27 Python
Python实现批量检测HTTP服务的状态
Oct 27 Python
Python简单实现两个任意字符串乘积的方法示例
Apr 12 Python
Python3中详解fabfile的编写
Jun 24 Python
python+mysql实现个人论文管理系统
Oct 25 Python
如何基于python测量代码运行时间
Dec 25 Python
python 实现线程之间的通信示例
Feb 14 Python
Python字符串split及rsplit方法原理详解
Jun 29 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重定向的三种方法分享
2012/02/22 PHP
php中配置文件操作 如config.php文件的读取修改等操作
2012/07/07 PHP
php判断字符串在另一个字符串位置的方法
2014/02/27 PHP
PHP empty函数报错解决办法
2014/03/06 PHP
浅谈php扩展imagick
2014/06/02 PHP
PHP获取一段文本显示点阵宽度和高度的方法
2015/03/12 PHP
详解PHP中cookie和session的区别及cookie和session用法小结
2016/06/12 PHP
Javascript实现的分页函数
2007/02/07 Javascript
JS判断元素为数字的奇异写法分享
2012/08/01 Javascript
ajax页面无刷新 IE下遭遇Ajax缓存导致数据不更新的问题
2012/12/11 Javascript
JavaScript如何实现对数字保留两位小数一位自动补零
2015/12/18 Javascript
JS面试题---关于算法台阶的问题
2016/07/26 Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(一)之数据支持json字符串、list集合
2016/08/11 Javascript
利用js编写响应式侧边栏
2016/09/17 Javascript
微信小程序 开发工具快捷键整理
2016/10/31 Javascript
JS关于刷新页面的相关总结
2018/05/09 Javascript
Vue.js实现数据响应的方法
2018/08/13 Javascript
Nodejs核心模块之net和http的使用详解
2019/04/02 NodeJs
深入了解JavaScript 私有化
2019/05/30 Javascript
js实现盒子拖拽动画效果
2020/08/09 Javascript
Python数组遍历的简单实现方法小结
2016/04/27 Python
python2 与 pyhton3的输入语句写法小结
2018/09/10 Python
python生成九宫格图片
2018/11/19 Python
python随机在一张图像上截取任意大小图片的方法
2019/01/24 Python
Python利用逻辑回归分类实现模板
2020/02/15 Python
Python并发concurrent.futures和asyncio实例
2020/05/04 Python
selenium3.0+python之环境搭建的方法步骤
2021/02/01 Python
解决virtualenv -p python3 venv报错的问题
2021/02/05 Python
C语言编程题
2015/03/09 面试题
小学节能减排倡议书
2014/05/15 职场文书
增员口号大全
2014/06/18 职场文书
仲裁协议书
2014/09/26 职场文书
四风对照检查剖析材料
2014/10/07 职场文书
小学运动会入场口号
2015/12/24 职场文书
幼儿教师师德培训心得体会
2016/01/09 职场文书
2016年党员创先争优公开承诺书
2016/03/25 职场文书