这两天遇到一个需求,需要修改5万多条数据。因我司iDb平台限制,超过500行的SQL均需提交给DBA手动执行,于是我使用Excel做好了5万多行SQL,放至文件中交给DBA,结果被告知因为要修改的是Oracle数据库,所以需要每1000行做一次commit,于是就想到了用Python来实现,结果不出所料,20行以内的代码搞定(不包含注释)。

由于我在生产环境执行的那个5W多行的SQL文件不便拿来举例,此处我们就再次使用Python脚本来生成一个SQL文件:

1
2
3
4
5
6
7
"""
生成5W行SQL,用于测试
"""
f = open("/Users/hongmao/test/test.sql", "w")
for i in range(50000):
    f.write(f"update user set status = 0 where id = {i};\n")
print("done!")

生成好之后,使用以下脚本来拼接commit

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
f = open('/Users/hongmao/test/test.sql', encoding='UTF-8')
f_result = open('/Users/hongmao/test/result.sql', 'w', encoding='UTF-8')

# 将每行数据读取到数组
lines = f.readlines()
print(f"数据读取完毕,共计{len(lines)}行")

# 声明计数器
counter = 0
for line in lines:
    # 逐行写到结果文件中
    f_result.write(line)
    # 计数器加1
    counter = counter + 1
    # 判断若达到1000行时,计数器归零,且拼接commit
    if counter == 1000:
        counter = 0
        f_result.write("commit;\n")
# 如果计数器为0,说明要么文件一行数据都没有,要么说明文件的数据行数正好是1000的整数倍
# 这时候,无需在末尾再次拼接commit了
if counter != 0:
    # 此处是判断原文件最后一行是否有换行符,如果没有就给其补一个
    # 不然会造成最后的commit和最后一行SQL处于同一行
    if not lines[len(lines) - 1].endswith("\n"):
        f_result.write("\n")
    f_result.write("commit;")

# 关闭文件
f.close()
f_result.close()
print("处理完毕!")

执行过后,在同一目录里的result.sql就是拼接好了commit;的脚本了。