Java получить результат из операторов вставки оракула - PullRequest
1 голос
/ 19 марта 2019

У меня есть небольшой и простой графический интерфейс, где пользователь может вставить некоторые операторы SQL вставки оракула и отправить их для вставки в БД.

У меня вопрос, как я могу получить статус результата и / илиОракул выводит операции и показывает его в графическом интерфейсе?Например, «X строк вставлено» или ошибка (например, трассировка стека исключений) в случае сбоя?

Мои 2 соответствующих метода приведены ниже - 1-й метод получает команды SQL из GUI и вызывает 2-й метод для запускаутверждение:

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
      String SQL = jEditorPane1.getText();
      jEditorPane1.setText("");
      String[] arraySQL = SQL.split(System.lineSeparator());
      for (String s : arraySQL) {
          System.out.println(s);
      }
      executeSQL(arraySQL);
}

 private void executeSQL(String[] commands) {      
        BasicDataSource dataSource = DatabaseUtility.getDataSource();     
        try (Connection connection = dataSource.getConnection()) {          
            for (String sql : commands) {
                try (PreparedStatement ps = connection.prepareStatement(sql)) {
                    ps.execute();
                }
            }
            connection.commit();           
        } catch (SQLException e) {            
            e.printStackTrace();
        } 
}

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Моя программа с открытым исходным кодом 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;
0 голосов
/ 21 марта 2019

Использование предложения @KevinO для использования метода executeUpdate() (для проверки вставленных записей) и в сочетании с тем, чтобы 2-й метод возвращал строку (либо "success", либо сообщение SQLException), сработало для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...