假设我有一个如下所示的 sql 脚本:
--split statement 1
ALTER TABLE abs
ADD (make VARCHAR2(2 byte),
model varCHAR2(12 BYTE),
built_on DATE,
serial varchar2(123 BYTE));
/
--split statement 2
declare
begin
null;
end;
/
--split statement 3
insert into test (v,a,c)
values ('1','jjoe;','232');
--split statement 4
create or replace function BLAH_BLAH(i_in varchar2)
as
l_one varchar2(12);
l_two varchar2(12);
l_three varchar2(12);
begin
l_one := 1;
l_two := 3;
insert into test (v,a,b)
values ('1','jjoee;','232');
exception when no_data_found then
l_three := 3;
end;
/
脚本基本上可以有 DML、DCL、DDL 和匿名 block 。我希望能够拆分每个语句并单独执行它们,但当然是为了它们出现的顺序。
我想到了使用正则表达式,我相信逻辑必须是这样的:
1) 如果字符串以 create|alter|drop|declare 开头,则获取从该字符串开头到分号的所有内容,然后是新行,然后是正斜杠(这里的关键是在匿名 block 的情况下,我们必须忽略 DML,直到到达终点)。
2) 如果字符串以 insert|delete|update|merge 开头(同样,如果我们已经在适用于要求 1 的 block 中,则忽略),获取从该字符串开头到分号的所有内容后跟一个没有正斜杠的换行符。
到目前为止,我已经在 Python 中想到了这个:
sql_commands = re.split('(?i)(((create|alter|drop|merge)+)(?m);(\s*)\n(\s*))|(;(\s*)\n(\s*)/)',sql_script)
但每次我尝试推进其他要求时,正则表达式开始不起作用(实际上输出有点古怪)并且变得复杂到足以让我迷失方向。
我想用 Python 或 Java 完成这个(我想,Java 实际上是首选,因为这是一个 oracle 数据库)
如果正则表达式不能胜任这项任务,则不必是正则表达式。我的最终目标是拆分每个语句并单独运行它,这样我就可以捕获出现的任何错误并妥善处理它们。
最佳答案
伪代码,未经测试,只是为了展示这个想法:
while (line = readLine()) {
String cmdString = null;
if (line.beginsWith("create" || line.beginsWith("alter") ...) {
String previousLine = line;
while (line = readLine()) {
if (line.equals("/") && previousLine.endsWith(";")) {
executeSQL(cmdString);
break;
}
previousLine = line;
cmdString = cmdString + line;
}
}
if (line.beginsWith("insert" || line.beginsWith("update") ...) {
String previousLine = line;
while (line = readLine()) {
if (line.equals("\n") && previousLine.endsWith(";")) {
executeSQL(cmdString);
break;
}
previousLine = line;
cmdString = cmdString + line;
}
}
// skip others
}
关于java - 一次将SQL脚本执行到oracle db中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13745753/