Python cx_Oracle执行kill session报ORA-00026错误问题排查
问题根因
触发ORA-00026是两个写法错误共同导致的:
- SQL变量用法错误:你把
:sid/:serial/:inst三个占位符写在了单引号内部,cx_Oracle不会替换引号内的占位符,Oracle实际收到的语句里,会话位置的文本就是字面量:sid, :serial,@:inst,根本不是合法的会话ID格式。另外alter system kill session语法本身就不支持把sid、序列号、实例ID拆成三个独立绑定变量传入,它要求后面跟一个符合格式的完整字符串。 - 代码缩进逻辑错误:你的
c.execute()写在CSV遍历循环的外部,连前面的print语句都在循环外,实际运行时只会读取CSV最后一行的字段值,根本不会逐行处理所有待清理会话。
修正方案
- 读取CSV字段后先做类型转换:把SID、Serial、Inst_ID都转成整数,同时自动过滤字段前后可能存在的空格,提前校验值合法性,也从根源避免SQL注入风险。
- 按照Oracle杀RAC会话的语法要求,把三个值拼接成
sid,serial,@inst_id格式的字符串,再嵌入SQL语句。 - 调整代码缩进,把会话处理、SQL执行的逻辑全部放到for循环内部,逐行处理CSV记录。
- 正式执行前先打印拼接好的会话标识,和原始CSV核对无误后再执行杀会话操作,避免误杀。
修正后代码
import csv import cx_Oracle # 以下数据库连接逻辑按你的实际环境配置 # conn = cx_Oracle.connect("dba_user/password@rac_service") # c = conn.cursor() with open(r'D:\hang_sessions.csv') as csv_file: csv_reader = csv.DictReader(csv_file, delimiter=',') for row in csv_reader: # 读取字段、去空格、转整数做合法性校验 sid = int(row['SID'].strip()) serial = int(row['Serial'].strip()) inst_id = int(row['Inst_ID'].strip()) # 拼接符合Oracle语法要求的会话串 kill_target = f"{sid},{serial},@{inst_id}" print(f"即将终止会话: {kill_target}") # 执行杀会话语句 c.execute(f"alter system kill session '{kill_target}' immediate") # 操作完成后释放资源 # c.close() # conn.close()
补充说明
- 如果是单实例Oracle(非RAC架构),不需要加实例ID部分,会话串拼接改成
f"{sid},{serial}"即可。 - 杀会话属于高危运维操作,建议先把execute行注释,跑一遍脚本看所有打印的
kill_target是否和预期一致,确认无误后再放开执行。 - 脚本里提前把三个字段转成整数,不存在SQL注入风险,可以安全使用。
内容的提问来源于stack exchange,提问作者Rizwan
相关产品推荐
相关产品推荐

