次のような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、および無名ブロックを含めることができます。各ステートメントを分割して個別に実行できるようにしたいのですが、もちろん、それらが表示される順序で。
正規表現を使用することを考えましたが、ロジックは次のようにする必要があると思います。
1) 文字列が create|alter|drop|declare で始まる場合、その文字列の先頭からセミコロンまでのすべてを取得し、その後に改行が続き、その後にスラッシュが続きます (ここで重要なのは、匿名ブロックのイベントでは、最後に到達するまで DML を無視する必要があります)。
2) 文字列が insert|delete|update|merge で始まる場合 (要件 1 に該当するブロックに既にいる場合は無視されます)、その文字列の先頭からセミコロンまでのすべてを取得します。スラッシュのない改行。
これまでのところ、Pythonでこれを思いつきました:
sql_commands = re.split('(?i)(((create|alter|drop|merge)+)(?m);(\s*)\n(\s*))|(;(\s*)\n(\s*)/)',sql_script)
しかし、他の要件を先に進めようとするたびに、正規表現が機能しなくなり (実際、出力はそのままではファンキーなものになります)、迷うほど複雑になります。
これをPythonまたはJavaで実行したいと思います(これがOracle dbであることを考えると、実際にはJavaの方が好ましいと思います)
正規表現が実際にこのタスクに対応していない場合、これは正規表現である必要はありません。私の最終的な目標は、各ステートメントを分割して個別に実行し、発生したエラーを見つけて適切に処理できるようにすることです。