共享利用Python脚本解决Oracle的SQL脚本@@用法
简介
Oracle客户端sql*plus正在执行某SQL脚本,当该SQL脚本调用同级目录的SQL脚本,会使用@@,请看详情的Oracle示例。崖山数据库23.2.x.100已支持@@用法,但是对于以前的版本,可以用Python脚本进行批量重写,对于存在@@调用的SQL文件,用SQL文件所在的绝对路径进行替换。
详情
Oracle示例
Oracle示例是在Windows上通过批处理脚本执行。
Windows批处理脚本 |
set ForkPath=%~dp0 echo %ForkPath%
cd %ForkPath% sqlplus xxx/xxx@xxx @1/demo1.sql
pause |
入口SQL脚本(1/demo1.sql)
1/demo1.sql |
spool demo1.log @@demo1_1.sql @@demo1_2.sql spool off exit |
入口SQL脚本(1/demo1.sql)调用同级目录的SQL脚本(1/demo1_1.sql和demo1_2)
1/demo1_1.sql |
select 'demo1_1' from dual; |
1/demo1_2.sql |
select 'demo1_2' from dual; |
Python脚本
Windows的Python脚本如下,如果运行在Linux上,请调整这一行newlines.append(line.replace("@@","@" + filename_dirname + "\\", 1))的'\\'为'/'即可
rewrite_o2y.py |
import os
def get_all_files(root_path): """ 递归获取指定路径下所有文件的绝对路径 :param root_path: 需要递归的根目录路径 :return: 文件绝对路径列表 """ # 初始化文件列表 all_files = []
# 获取根目录下的所有文件和目录 for dir_path, dir_names, file_names in os.walk(root_path): # 遍历文件 for file_name in file_names: # 获取文件的绝对路径并添加到列表中 file_path = os.path.join(dir_path, file_name) all_files.append(file_path)
return all_files
if __name__ == '__main__': # 获取脚本所在路径 current_path = os.path.dirname(os.path.abspath(__file__)) print("当前目录是:", current_path)
filenames = get_all_files(current_path) for filename in filenames: if filename.endswith(".sql"): filename_dirname = os.path.dirname(filename) filename_basename = os.path.basename(filename) filename_orig = filename + ".orig"
print("\n当前处理: "+filename) # 读取所有行 with open(filename, 'r') as file: lines = file.readlines()
need_rename_file = False newlines = [] for line in lines: # 替换以@@为@+绝对路径 if line.startswith("@@"): newlines.append(line.replace("@@","@" + filename_dirname + "\\", 1)) need_rename_file = True else: newlines.append(line)
for newline in newlines: print(newline, end="")
if need_rename_file: # 重命名文件 os.rename(filename, filename_orig) # 写回文件 with open(filename, 'w') as file: file.writelines(newlines)
print("\n处理完毕: " + filename) |
用法
cd %Oracle示例所在的目录% python rewrite_o2y.py |
运行
D:\Workspace\Demo\python_demo>python rewrite_o2y.py 当前目录是: D:\Workspace\Demo\python_demo
当前处理: D:\Workspace\Demo\python_demo\demo2\1\demo1.sql spool demo1.log @D:\Workspace\Demo\python_demo\demo2\1\demo1_1.sql @D:\Workspace\Demo\python_demo\demo2\1\demo1_2.sql spool off exit 处理完毕: D:\Workspace\Demo\python_demo\demo2\1\demo1.sql
当前处理: D:\Workspace\Demo\python_demo\demo2\1\demo1_1.sql select 'demo1_1' from dual; 处理完毕: D:\Workspace\Demo\python_demo\demo2\1\demo1_1.sql
当前处理: D:\Workspace\Demo\python_demo\demo2\1\demo1_2.sql select 'demo1_2' from dual; 处理完毕: D:\Workspace\Demo\python_demo\demo2\1\demo1_2.sql |
结果
入口SQL脚本(1/demo1.sql)的@@被替换成绝对路径
1/demo1.sql |
spool demo1.log @D:\Workspace\Demo\python_demo\demo2\1\demo1_1.sql @D:\Workspace\Demo\python_demo\demo2\1\demo1_2.sql spool off exit |
原入口SQL脚本(1/demo1.sql)被重命名为(1/demo1.sql.orig)
1/demo1.sql.orig |
spool demo1.log @@demo1_1.sql @@demo1_2.sql spool off exit |
其他SQL文件都保持不变,然后调整批处理脚本即可在YashanDB运行
Windows批处理脚本 |
set ForkPath=%~dp0 echo %ForkPath%
cd %ForkPath% yasql xxx/xxx@xx.xx.x.x:xxxx -f 1/demo1.sql
pause |