2017-02-15 79 views
0

當使用給出DBMS_OUTPUT.CHARARR結果的DBMS_OUTPUT.GET_LINES時,如何將其轉換爲varchar2?我想使用DBMS_OUTPUT.GET_LINES來獲取我的所有DBMS_PUTLINE語句,並將它們作爲字符串返回給調用程序。如何將DBMS_OUTPUT.GET_LINES轉換爲VARCHAR2?

數據庫:Oracle 12c中

PLSQL版本:版本11.0.6.1776

declare 
    -- Non-scalar parameters require additional processing 

    v_Data  DBMS_OUTPUT.CHARARR; 
    v_NumLines NUMBER; 
begin 
    -- Call the procedure 


    -- Procedure that will generate DMBS_OUTPUT.PUT_LINEs 
    executeProcFoo(); 

    v_NumLines := 1000; 
    DBMS_OUTPUT.GET_LINES(v_Data, v_NumLines); 

    FOR v_Counter IN 1..v_NumLines LOOP 
     --output putlines from get_lines 
     DBMS_OUTPUT.put_line(v_Data(v_Counter)); 
    END LOOP; 
end; 
+0

'dbms_output.chararr'已經是一個'varchar2'數組。你把它轉換成'varchar2'是什麼意思?你想要一個長串嗎?或者您是否需要將其發佈爲與您的調用框架更兼容的其他集合類型? –

+0

是一個長字符串。我想將結果作爲一個字符串返回給調用的Java應用程序。 – haju

+0

爲什麼?當然Java有數組?但無論如何,只需循環遍歷數組,將其附加到合適的文本變量。我仍然沒有看到技術問題。 –

回答

0

試試這個:

DECLARE 
    -- Non-scalar parameters require additional processing 

    v_Data  DBMS_OUTPUT.CHARARR; 
    v_NumLines NUMBER; 

    TYPE v IS TABLE OF VARCHAR2 (1000) 
       INDEX BY BINARY_INTEGER; 

    v_var  v; 
BEGIN 
    -- Call the procedure 


    -- Procedure that will generate DMBS_OUTPUT.PUT_LINEs 
    DBMS_OUTPUT.PUT_LINE ('vvvv'); 
    DBMS_OUTPUT.put_line ('xxxxx'); 

    v_NumLines := 1000; 
    DBMS_OUTPUT.GET_LINES (v_Data, v_NumLines); 

    FOR v_Counter IN v_data.FIRST .. v_data.LAST 
    LOOP 
     --output putlines from get_lines 
     DBMS_OUTPUT.put_line (v_Data (v_Counter)); 
     v_var (v_counter) := v_data (v_counter); 
    END LOOP; 
END; 

然後,您可以通過v_var任何過程或函數。

+0

我想返回一個單一的字符串到Java調用這個存儲過程。在那種情況下,我會通過遍歷v的表來構建varchar2來構建返回的最終字符串嗎? – haju

+0

是的,你可以做到這一點。 –

2

從註釋看來,您似乎只是在尋找一種方便的方法將DBMS_OUTPUT緩衝區提取到Java應用程序中。儘管可以將SQL類型發佈爲與Java兼容的數組(我不是Java開發人員,但我會將其留給其他人 - 但請注意,dbms_output.get_lines已超載,並且可能會返回dbmsoutput_linesarray,這可能比使用dbms_output.chararray),我想到一個引用遊標可能會做到這一點。

如果是這樣,你可以創建一個返回的輸出緩衝區作爲集合函數:

create or replace function get_dbms_output 
    return dbmsoutput_linesarray 
as 
    l_output dbmsoutput_linesarray; 
    l_linecount number; 
begin 
    dbms_output.get_lines(l_output, l_linecount); 

    if l_output.count > l_linecount then 
     -- Remove the final empty line above l_linecount 
     l_output.trim; 
    end if; 

    return l_output; 
end get_dbms_output; 

現在,你可以發出一個正常的SQL查詢作爲

select column_value from table(get_dbms_output) 

這應該給你一個標準參考遊標。

演示:

SQL> set serveroutput off 
SQL> 
SQL> begin 
    2  dbms_output.enable; 
    3  dbms_output.put_line('This is a line'); 
    4  dbms_output.put_line('This is another line'); 
    5  dbms_output.put_line('This is the last line.'); 
    6 end; 
    7/

PL/SQL procedure successfully completed. 

SQL> select column_value from table(get_dbms_output); 

COLUMN_VALUE 
-------------------------------------------------------- 
This is a line 
This is another line 
This is the last line. 

3 rows selected. 

(該set serveroutput off剛剛停止的SQL * Plus從在通話結束做自己的dbms_output.get_lines並留下我的功能無事可做的dbms_output.enable是因爲set serveroutput off禁用DBMS_OUTPUT。 。這些僅用於SQL * Plus中的演示目的,您不需要Java中的任何一個。)

+0

對於column_value,變量類型是什麼? – haju

+0

啊,好點 - 它是'varchar2(32767)',現在我想起它可能會給你一些超過4000字節的行的問題(除非你在Oracle 12c上,並且你已經[啓用擴展數據類型]( https://oracle-base.com/articles/12c/extended-data-types-12cR1))。 –

+0

我剛剛測試了一個4001字符的行,並且它失敗了'ORA-24920:列大小對於客戶端來說太大了,儘管我懷疑如果客戶端沒有拒絕這個值,它仍然會失敗。也許我可以讓它成爲一個流水線函數,讓它檢查每一行並在必要時分割它,所以它不會失敗,但它可能會破壞一些格式並將一些單詞分成兩部分,除非我添加更多的邏輯。 –

相關問題