Z.S.K.'s Records

python中调用sqlplus

在python中查询Oracle,首先当然是cx_Oracle,方便快捷,但是很无奈有时必须使用sqlplus命令的形式,比如生成oracle9i的statspack报告,cx_Oracle就无能为力了,同时,这也涉及到python中子进程调用的问题,简单的任务当然首选subprocess

subprocess

talk is cheap,show me your code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import subprocess
class oracleversion():
def __init__(self,username,password,databaseName):
self.username = username
self.password = password
self.databaseName = databaseName
def run(self):
try:
oraclever = "sqlplus -S " + self.username + "/" + self.password + "@" + self.databaseName
child = subprocess.Popen(oraclever,shell=True,stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
child.stdin.write(b"select * from v$version where rownum<2;")
return child.communicate()
#print("<<%s done.>>" %self.city)
except Exception as e:
err_txt = "ERROR: 调用ORACLE SQLPLUS失败!"
print(err_txt)
write_errtxt(err_txt)

上面则是一个简单的判断oracle的版本,因为oracle的版本不同,涉及到后续的操作流程不一样,首先import subprocess

使用Popen fork一个子进程,子进程调用sqlplus,大多数的时候我们是需要在sqlplus中执行命令,如何与子进程进行交互呢?

subprocess.Popen

child=subprocess.Popen(oraclever,shell=True,stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE)

首先我们需要在父子进程之间形成一个管道(PIPE),通过这个管道进行交互,父进程可以给子进程输入,子进程得到输入处理后把输出或者是错误信息返回给父进程,shell=True表示使用shell执行

child.stdin.write()

这便是向子进程传递输入,这里有个注意的地方:

对于python2.x,这里直接传递sql语句没问题

但是对于python3.x,必须将字符串转换成字节串,直接在字符串前加b,得到的输出则需要decode()转换成字符串

(out,err)=child.communicate()

这句话其实返回的是一个元组,元组前表示输出,后者表示错误信息

child.wait()

该函数迫使父进程等待子进程执行完之后再往下执行,返回命令执行后的返回值

Popen.poll()

用于检查子进程是否已经结束

Popen.terminate()

停止(stop)子进程

Popen.kill()

杀死子进程

参考文章:

转载请注明原作者: 周淑科(https://izsk.me)


 wechat
Scan Me To Read on Phone
I know you won't do this,but what if you did?