• 技术文章 >后端开发 >Python教程

    Python调用SQLPlus来操作和解析Oracle数据库的方法

    2016-06-10 15:05:19原创1253
    先来看一个简单的利用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", "//m.sbmmt.com/m/", "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 <
    

    其中os.environ['NLS_LANG']的值来自

    select userenv['language'] from dual;
    
    

    在调用的时候,只要类似:

    listResult = QueryBySqlPlus('select * from studentinfo')
    

    然后就可以用循环打印出结果了。

    php入门到就业线上直播课:查看学习

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。

    千万级数据并发解决方案(理论+实战):点击学习

    Mysql单表千万级数据量的查询优化与性能分析

    Mysql主从原理及其在高并发系统中的应用

    专题推荐:Python SQLPlus Oracle

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• Python NumPy教程之数据类型对象• 使用Python处理KNN分类算法• Python标准库中的logging用法示例• python发腾讯微博代码分享• python自动化测试实例解析
    1/1

    PHP中文网