如何在Python 2.7中将SQL*Plus输出转换为二维元组
解决Python调用SQL*Plus输出解析为二维元组的问题
嘿,这个问题我太熟了——SQLPlus默认的输出格式就是给人看的,完全不适合程序解析。咱们分两步来搞定:先让SQLPlus输出规整的机器友好格式,再把输出转换成你要的二维元组,还能完美保留空值。
第一步:让SQL*Plus输出“可解析”的格式
默认输出里的横线、换行错位、空值显示成NULL都是坑,我们可以在查询前加一串SQL*Plus的set命令,强制输出带分隔符的规整内容:
from subprocess import Popen, PIPE def runSqlQuery(sqlCommand, connectString): # 这些命令是格式化核心,按需调整分隔符和行宽 format_setup = """ set colsep '|' -- 设置列分隔符为|,选个不会出现在字段内容里的字符 set pagesize 0 -- 移除表头和数据之间的横线分隔行 set trimspool on -- 自动去除字段前后的多余空格 set heading on -- 保留表头行 set null '' -- 空值直接输出为空字符串,替代默认的NULL set linesize 2000 -- 设置足够宽的行,避免长字段被强制换行 """ # 拼接格式命令、查询命令和退出命令 full_sql = format_setup + sqlCommand + "\nexit;" # Python2.7需注意编码,将字符串转为字节流写入 session = Popen(['sqlplus', '-S', connectString], stdin=PIPE, stdout=PIPE, stderr=PIPE) session.stdin.write(full_sql.encode('utf-8')) stdout, stderr = session.communicate() # 解码为字符串,根据数据库字符集调整(比如gbk或utf-8) return stdout.decode('utf-8'), stderr.decode('utf-8')
第二步:解析输出为目标二维元组
现在SQL*Plus的输出会变成规整的分隔符格式,比如:
PERSONID|PAYROLLNUMBER|EMPLOYEEPREFIX|LASTNAME|FIRSTNAME|MI|ACTIVE|UN_ID 11111|99999||NEWMAN|ALFRED||1|
接下来写解析函数,把这个格式转换成你需要的二维元组:
def parse_to_tuple(output): # 按行分割,过滤空行和多余提示行 lines = [line.strip() for line in output.split('\n') if line.strip()] if not lines: return () # 处理表头:分割后去除列名前后空格 headers = [col.strip() for col in lines[0].split('|')] # 处理数据行:分割后保留空值,确保列数与表头对齐 data_rows = [] for line in lines[1:]: row = [col.strip() for col in line.split('|')] # 若某行因格式问题列数不足,补上空字符串对齐 while len(row) < len(headers): row.append('') data_rows.append(row) # 组合成二维元组(第一行为列名,后续为数据行) return (headers,) + tuple(data_rows)
调用示例
沿用你原来的调用逻辑,加上解析步骤即可:
# 替换为你的实际参数 username = "your_username" password = "your_password" sqlCommand='select * from <database-name-removed> where payrollnumber in (1111);' connectString=username + '/' + password + '@SERVER' # 执行查询 queryResult, errorMessage = runSqlQuery(sqlCommand, connectString) # 处理结果 if errorMessage: print(f"执行出错:{errorMessage}") else: result_tuple = parse_to_tuple(queryResult) print(result_tuple)
关键细节提醒
- 编码适配:Python2.7中subprocess的输出是字节流,解码时要匹配数据库字符集(比如Oracle常用的
GBK或AL32UTF8),乱码时换个编码试试。 - 分隔符选择:如果字段内容可能包含
|,换成更特殊的分隔符(比如^或~~);Oracle 12c及以上版本可直接用set markup csv on输出CSV格式,解析更省心。 - 空值保留:
set null ''命令确保空值被输出为空字符串,解析时无需额外转换即可保留。
这样处理后,你就能得到完全符合需求的二维元组,空值也会被正确保留。
内容的提问来源于stack exchange,提问作者TronixA
相关产品推荐
相关产品推荐

