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 相关文章推荐
Python3通过Luhn算法快速验证信用卡卡号的方法
May 14 Python
Python简单实现自动删除目录下空文件夹的方法
Aug 29 Python
Django安装配置mysql的方法步骤
Oct 15 Python
python学生管理系统开发
Jan 30 Python
Python实现FM算法解析
Jun 18 Python
python栈的基本定义与使用方法示例【初始化、赋值、入栈、出栈等】
Oct 24 Python
python 实现方阵的对角线遍历示例
Nov 29 Python
Python常用模块os.path之文件及路径操作方法
Dec 03 Python
python构造函数init实例方法解析
Jan 19 Python
关于python中的xpath解析定位
Mar 06 Python
详解python中的异常捕获
Dec 15 Python
python装饰器代码深入讲解
Mar 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环境搭建最新方法
2006/09/05 PHP
递归列出所有文件和目录
2006/10/09 PHP
PHP字符串的递增和递减示例介绍
2014/02/11 PHP
php修改指定文件后缀的方法
2014/09/11 PHP
mysql_escape_string()函数用法分析
2016/04/25 PHP
Yii框架表单模型和验证用法
2016/05/20 PHP
Lumen timezone 时区设置方法(慢了8个小时)
2018/01/20 PHP
thinkphp框架类库扩展操作示例
2019/11/26 PHP
javascript实现的元素拖动函数宿主为浏览器
2014/07/21 Javascript
基于jquery实现的自动补全功能
2015/03/12 Javascript
jQuery中$this和$(this)的区别介绍(一看就懂)
2015/07/06 Javascript
JS文字球状放大效果代码分享
2015/08/19 Javascript
创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件
2016/06/02 Javascript
为输入框加入数字js校验代码分享
2017/11/02 Javascript
jQuery第一次运行页面默认触发点击事件的实例
2018/01/10 jQuery
Javascript中弹窗confirm与prompt的区别
2018/10/26 Javascript
vue实现微信分享功能
2018/11/28 Javascript
nodejs 使用 js 模块的方法实例详解
2018/12/04 NodeJs
用webpack4开发小程序的实现方法
2019/06/04 Javascript
CKEditor 4.4.1 添加代码高亮显示插件功能教程【使用官方推荐Code Snippet插件】
2019/06/14 Javascript
vue实现动态表格提交参数动态生成控件的操作
2020/11/09 Javascript
[01:09]模型精美,特效酷炫!TI9不朽宝藏Ⅰ鉴赏
2019/05/10 DOTA
python 排列组合之itertools
2013/03/20 Python
讲解Python中的标识运算符
2015/05/14 Python
python numpy函数中的linspace创建等差数列详解
2017/10/13 Python
python 画3维轨迹图并进行比较的实例
2019/12/06 Python
一款利用html5和css3实现的3D立方体旋转效果教程
2016/04/26 HTML / CSS
英国最大的女士服装零售商:Bonmarché
2017/08/17 全球购物
英国的屈臣氏:Boots博姿
2017/12/23 全球购物
Topshop法国官网:英国快速时尚品牌
2018/04/08 全球购物
YOOX台湾:意大利奢侈品电商
2018/10/13 全球购物
印度民族服装购物网站:BIBA
2019/08/05 全球购物
应聘英语教师求职信
2014/04/24 职场文书
我爱我班主题班会
2015/08/13 职场文书
导游词之无锡梅园
2019/11/28 职场文书
苹果的回收机器人可以通过拆解iPhone获取大量的金和铜并外公布了环境保护最新进展
2022/04/21 数码科技