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流程控制语句
Dec 04 Python
简单易懂的python环境安装教程
Jul 13 Python
利用python模拟实现POST请求提交图片的方法
Jul 25 Python
Python网络编程详解
Oct 31 Python
Python登录并获取CSDN博客所有文章列表代码实例
Dec 28 Python
Python实现的圆形绘制(画圆)示例
Jan 31 Python
详解Pytorch 使用Pytorch拟合多项式(多项式回归)
May 24 Python
Python使用pandas对数据进行差分运算的方法
Dec 22 Python
Python3.8对可迭代解包的改进及用法详解
Oct 15 Python
From CSV to SQLite3 by python 导入csv到sqlite实例
Feb 14 Python
python求前n个阶乘的和实例
Apr 02 Python
Python集合的基础操作
Nov 01 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 冒泡排序 二分查找 顺序查找 二维数组排序算法函数的详解
2013/06/25 PHP
php实现与erlang的二进制通讯实例解析
2014/07/23 PHP
PHP删除数组中指定值的元素常用方法实例分析【4种方法】
2018/08/21 PHP
javascript 火狐(firefox)不显示本地图片问题解决
2008/07/05 Javascript
在IE6下发生Internet Explorer cannot open the Internet site错误
2010/06/21 Javascript
jquery slibings选取同级其他元素的实现代码
2013/11/15 Javascript
JS两种定义方式的区别、内部原理
2013/11/21 Javascript
JQuery做的一个简单的点灯游戏分享
2014/07/16 Javascript
使用JQuery FancyBox插件实现图片展示特效
2015/11/16 Javascript
javaScript知识点总结(必看篇)
2016/06/10 Javascript
AngularJS 实现弹性盒子布局的方法
2016/08/30 Javascript
jQuery查找节点并获取节点属性的方法
2016/09/09 Javascript
jQuery实现带延时功能的水平多级菜单效果【附demo源码下载】
2016/09/21 Javascript
angular双向绑定模拟探索
2016/12/26 Javascript
Vue.js系列之vue-router(上)(3)
2017/01/03 Javascript
AngularJS的ng-click传参的方法
2017/06/19 Javascript
JavaScript创建对象的七种方式(推荐)
2017/06/26 Javascript
jQuery EasyUI Layout实现tabs标签的实例
2017/09/26 jQuery
微信小程序数字滚动插件使用详解
2018/02/02 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
2019/08/09 Javascript
antd-mobile ListView长列表的数据更新遇到的坑
2020/04/08 Javascript
[53:38]OG vs LGD 2018国际邀请赛淘汰赛BO3 第三场 8.26
2018/08/30 DOTA
python3 requests中使用ip代理池随机生成ip的实例
2018/05/07 Python
Python设计模式之职责链模式原理与用法实例分析
2019/01/11 Python
高级Java程序员面试要点
2013/08/02 面试题
结构工程个人自荐信范文
2013/11/30 职场文书
材料加工工程求职信
2014/02/19 职场文书
《云雀的心愿》教学反思
2014/02/25 职场文书
法制宣传实施方案
2014/03/13 职场文书
教师自我剖析材料范文
2014/09/30 职场文书
工作收入住址证明
2014/10/28 职场文书
幼儿园见习报告范文
2014/10/30 职场文书
ORACLE数据库对long类型字段进行模糊匹配的解决思路
2021/04/07 Oracle
Python中的min及返回最小值索引的操作
2021/05/10 Python
Pytorch distributed 多卡并行载入模型操作
2021/06/05 Python
MySql子查询IN的执行和优化的实现
2021/08/02 MySQL