最近抽时间学习了一下python连接oracle进行sql处理,用到了cx_Oracle库,现把重点步骤记录一下
一、开发环境:Python2.7, cx_Oracle的版本是5.1.2,Oracle版本是10g
二、导入库import cx_Oracle
三、连接及断开数据库连接# 连接数据库,数据库名应该是在本地tns中配置
database = '数据库名'
user = '用户名'
passwd = '密码'
url = user + '/' + passwd + '@' + database # 连接字符串
db = cx_Oracle.connect(url) # 连接数据库
# 断开数据库
db.close()
四、查询数据# 声明游标
cur = db.cursor()
# 执行SQL
sql = 'select sysdate from dual'
_ = cur.execute(sql)
# 取数据
rows = cur.fetchall() # 一次性取出所有数据
row = cur.fetchone() # 每次只取一行数据,下次调用取下一行
rows = cur.fetchmany(200) # 每次只取200行数据,下次调用取下200行
# 对于cur.fetchall()取出的数据
# 我们可以用下标取数
t = rows[0][0]
# 也可以遍历rows
for row in rows:
for col in row:
print col
# 总行数
len( rows)
# 总列数
len( rows[0])
# 对于cur.fetchone()取出的数据
# 我们可以判断结果是否是None来判断是否已经取完数据
if row == None:
print '数据已取完'
# 我们可以用下标取数
t = row[0]
# 也可以遍历row
for col in row:
print col
# 总列数
len( row)
# 对于cur.fetchmany(200)取出的数据
# 我们可以判断结果的行数是否是0来判断是否已经取完数据
if len(rows) == 0:
print '数据已取完'
# 我们可以用下标取数
t = row[0][0]
# 也可以遍历rows
for row in rows:
for col in row:
print col
# 已取出行数
len( rows)
# 总列数
len( rows[0])
# 取列类型及名称
# 在调用cur.execute(sql)之后执行
# 第一列的名称
cur.description[0][0]
# 第一列的类型
cur.description[0][1]
# 列类型常用的有:
# 字符串 cx_Oracle.STRING
# 日期时间 cx_Oracle.DATETIME
# 数字 cx_Oracle.NUMBER
# CLOB cx_Oracle.CLOB
# BLOB cx_Oracle.BLOB
# 取出值的转换
# 如果列类型不是cx_Oracle.STRING,那么我们可以使用函数str对取出的值进行转换
# 我们可以通过如下代码判断取出的值是不是null
if str(type(col)) == "":
print "变量col的值是null"
# 关闭游标
cur.close()
如果要执行的sql绑定了变量,则代码如下a = 1
b = 2
sql = 'select :a + :b as col from dual'
_ = cur.execute(sql,{'a':a,'b':b})
# 或
cur.prepare(sql)
_ = cur.execute(None,{'a':a,'b':b}) # 注意第一个参数是None,因为上一条语句已经传入了SQL
# 或
sql = 'select :1 + :2 as col from dual'
_ = cur.execute(sql,(a,b)) # a对应:1,b对应:2
# 当然了,这里我们也可以用prepare的用法,在此不累述
# 这里有两点需要特别注意一下
# 1. 如果sql写成 sql = 'select :2 + :1 as col from dual', execute第二个参数仍为(a,b)
# 那么a对应:2, b对应:1
# 2. 如果sql中只有一个:1,那么execute第二个参数应该是(a,),注意后面得加一个逗号,表示这是一个tuple,而不是普通变量
五、增删改数据# 准备SQL
sql = "insert into t_temp_test( n_00, t_00, c_00) values( 123, sysdate, 'hello')"
# 执行SQL
cur.execute(sql)
# 取影响的记录数
cur.rowcount
# 提交
db.commit()
# 回滚
db.rollback()
# 在准备及执行SQL时,还可以用我们上节讲过的绑定变量的方法
sql = "insert into t_temp_test( n_00, t_00, c_00) values( :1, sysdate, :2)"
cur.execute(sql,(456,'world'))
六、捕捉SQL异常try:
sql = "insert into t_temp_test( n_00, t_00, c_00) values( :1, '123', :2)"
cur.execute(sql,(456,'world'))
except cx_Oracle.Error as e:
e, = e.args
print e.code # 捕捉到sqlcode
七、中文字符集处理# 连接数据库之前,定义环境变量NLS_LANG
import os
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.ZHS16GBK' # 后面的内容要和数据库的一致,可以通过plsql查看
# 如果出现乱码,可以考虑适时加上代码decode('gbk')修正
八、调用存储过程# create or replace procedure p_temp_test( v_arg in varchar2)
# is
# begin
# dbms_output.put_line( v_arg);
# end p_temp_test;
cur.callproc('p_temp_test',('hello',))
九、调用函数# create or replace function cur_time
# return date is
# begin
# return sysdate;
# end;
cur.callfunc('cur_time',cx_Oracle.DATETIME) # 第三个参数应该是参数,此例中没有涉及,请参考上一节内容