Моя программа с открытым исходным кодом PLSQL_LEXER может помочь вам с вашей задачей.
Похоже, вы пытаетесь установить уменьшенную версию SQL Fiddle, что является сложной задачей. Существует множество странных проблем при разборе, классификации и выполнении операторов SQL. Я не могу помочь вам с Java-вещью, но если вы готовы выполнить большую часть тяжелой работы в PL / SQL, то приведенный ниже код должен помочь.
Если вы установите пакет, а затем создадите хранимую функцию ниже, вы можете просто передать строку (CLOB) в Oracle, а затем получить результаты обратно.
Код также показывает, как запретить запуск определенных видов команд. Но это только для удобства, если хотите предупредить людей не запускать определенные вещи. Вы не хотите попробовать заново внедрить систему безопасности Oracle здесь. Вы должны предположить, что любой, кто отправляет команды этой функции, имеет все те же привилегии, что и пользователь, которому принадлежит эта функция.
create or replace function run_commands(p_statements clob) return clob
as
v_split_statements token_table_table;
v_category varchar2(100);
v_statement_type varchar2(100);
v_command_name varchar2(64);
v_command_type number;
v_lex_sqlcode number;
v_lex_sqlerrm varchar2(4000);
v_output clob;
begin
--Tokenize and split the string into multiple statements.
v_split_statements := statement_splitter.split_by_semicolon(
plsql_lexer.lex(p_statements));
--Loop through the statements.
for i in 1 .. v_split_statements.count loop
--Classify each statement.
statement_classifier.classify(
p_tokens => v_split_statements(i),
p_category => v_category,
p_statement_type => v_statement_type,
p_command_name => v_command_name,
p_command_type => v_command_type,
p_lex_sqlcode => v_lex_sqlcode,
p_lex_sqlerrm => v_lex_sqlerrm
);
--For debugging, print the statement and COMMAND_NAME.
v_output := v_output||chr(10)||'Statement '||i||' : '||
replace(replace(
plsql_lexer.concatenate(v_split_statements(i))
,chr(10)), chr(9));
v_output := v_output||chr(10)||'Command Name: '||v_command_name;
--Handle different command types.
--
--Prevent Anonymous Blocks from running.
if v_command_name = 'PL/SQL EXECUTE' then
v_output := v_output||chr(10)||'Error : Anonymous PL/SQL blocks not allowed.';
--Warning message if "Invalid" - probably a typo.
elsif v_command_name = 'Invalid' then
v_output := v_output||chr(10)||'Warning : Could not classify this statement, '||
'please check for a typo: '||
replace(replace(substr(
plsql_lexer.concatenate(v_split_statements(i))
, 1, 30), chr(10)), chr(9));
--Warning message if "Nothing"
elsif v_command_name = 'Nothing' then
v_output := v_output||chr(10)||'No statements found.';
--Run everything else.
else
declare
v_success_message varchar2(4000);
v_compile_warning_message varchar2(4000);
begin
--Remove extra semicolons and run.
execute immediate to_clob(plsql_lexer.concatenate(
statement_terminator.remove_semicolon(
p_tokens => v_split_statements(i))));
--Get the feedback message.
statement_feedback.get_feedback_message(
p_tokens => v_split_statements(i),
p_rowcount => sql%rowcount,
p_success_message => v_success_message,
p_compile_warning_message => v_compile_warning_message
);
--Print success message.
v_output := v_output||chr(10)||'Status : '||v_success_message;
--Print compile warning message, if any.
--This happens when objects successfully compile but are invalid.
if v_compile_warning_message is not null then
v_output := v_output||chr(10)||'Compile warning: '||v_compile_warning_message;
end if;
exception when others then
v_output := v_output||chr(10)||'Error : '||dbms_utility.format_error_stack||
dbms_utility.format_error_backtrace;
end;
end if;
end loop;
return v_output;
end;
/
Ниже приведен пример запуска хранимой процедуры и вывода. Вам придется конвертировать этот блок PL / SQL в вызов Java, но я не думаю, что это будет слишком сложно.
declare
--A collection of statements separated by semicolons.
--These may come from a website, text file, etc.
v_statements clob := q'<
create table my_table(a number);
insert into my_table values(1);
begin null; end;
udpate my_table set a = 2;
>';
v_results clob;
begin
v_results := run_commands(v_statements);
dbms_output.put_line(v_results);
end;
/
Statement 1 : create table my_table(a number);
Command Name: CREATE TABLE
Status : Table created.
Statement 2 : insert into my_table values(1);
Command Name: INSERT
Status : 1 row created.
Statement 3 : begin null; end;
Command Name: PL/SQL EXECUTE
Error : Anonymous PL/SQL blocks not allowed.
Statement 4 : udpate my_table set a = 2;
Command Name: Invalid
Warning : Could not classify this statement, please check for a typo: udpate my_table set a = 2;