簡體   English   中英

java從oracle插入語句中獲取結果

[英]java get result from oracle insert statements

我有一個小而簡單的 gui,用戶可以在其中粘貼一些 oracle insert SQL 語句並將它們提交到數據庫中。

我的問題是,如何檢索操作的結果狀態和/或 oracle 輸出並將其顯示在 GUI 上? 例如“插入 X 行”或失敗時的錯誤(例如異常堆棧跟蹤)?

我的 2 個相關方法如下 - 第一種方法從 GUI 獲取 SQL 命令並調用第二種方法來運行語句:

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();
        } 
}

我的開源程序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;

使用@KevinO 建議使用executeUpdate()方法(檢查插入的記錄),並結合使第二個方法返回一個字符串(“成功”或 SQLException 消息),對我有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM