2014-03-29 86 views
1

如何動態讀取n個元素的數組並顯示plsql中的元素。從用戶輸入讀取「n」個元素的數組

下面是我的代碼(我是新來的PLSQL編程)

set serveroutput on 
set verify on 
declare 
    type myarray is table of number index by binary_integer; 
    x myarray; 
    i pls_integer; 
    n number; 

begin 
    -- populate array 
    dbms_output.put_line('Enter number of array elements'); 
    n := &n; 
    dbms_output.put_line('Enter elements one by one'); 
    for i in 1..n loop 
    dbms_output.get_lines(&&x(i),n); 
    end loop; 
    i :=0; 

    -- print array 
    loop 
      i := i + 1; 
      begin 
        dbms_output.put_line(x(i)); 
      exception 
        when no_data_found then exit; 
      end; 
    end loop; 

    end; 
/
    quit; 
+1

dbms_output.get_line不會從輸入中讀取數據。它從dbms_output緩衝區中讀取行。你正在將sql * plus命令與pl/sql混淆。 – OldProgrammer

+0

請幫助我如何做到這一點 – user3422419

+3

用一個音節的話說 - 你不能。 PL/SQL沒有設置爲接受交互式用戶輸入。我建議你將數組元素放在一個文件中並逐行讀取文件(請參閱UTL_FILE包),使用TO_NUMBER將從文件中讀取的字符串轉換爲數字,然後將這些數字存儲到數組中。但我不熟悉使用PL/SQL從終端讀取輸入。祝你好運。 –

回答

0

我跌入了同樣的問題,並想嘗試的東西。

您可以用一種殘酷的方法來做到這一點,即在任何時候想要爲陣列添加值時使用shell調用客戶端(即sqlplus)。我寫了一個將數組的值存儲在表中的小包。然後你就可以改變你的存儲值的方式,但原則將保持不變:

-- this package uses "execute immediate" statements for everything 
-- because it assumes the temporary table T_MY_ARRAY can be non-existent. 
create or replace package my_array 
    authid current_user 
is 
    TYPE a_TBL_Number IS TABLE OF Number INDEX BY BINARY_INTEGER; 
    procedure init; 
    procedure add(v in number); 
    procedure display; 
    function to_var return a_TBL_Number; 
end my_array; 
/
create or replace package body my_array 
is  
    procedure init is 
    -- create table if needed, then make sure its empty; 
    begin 
    begin 
     execute immediate 'create table T_MY_ARRAY(c1 number)'; 
    exception when others then 
     -- dbms_output.put_line(sqlerrm); 
     -- we're never sure the temp. table already exists. So create it and catch if existing. 
     null; 
    end; 
    execute immediate 'truncate table T_MY_ARRAY'; 
    end init; 

    procedure add(v in number) is 
    -- add new value 
    begin 
    execute immediate 'insert into T_MY_ARRAY (c1) values ('||v||')'; 
    end add; 

    function to_var return a_TBL_Number is 
    -- hand out an array with the values 
    t_TBL_n a_TBL_Number; 
    begin 
    execute immediate 'select c1 from T_MY_ARRAY ' bulk collect into t_TBL_n; 
    return t_TBL_n; 
    end to_var; 

    procedure display is 
    t_TBL_n a_TBL_Number; 
    begin 
    t_TBL_n:=my_array.to_var(); 
    for i in 1..t_TBL_n.count loop 
     dbms_output.put_line(t_TBL_n(i)); 
    end loop; 
    end display; 

end my_array; 
/

那麼這裏就是你怎麼可以從外殼調用這個(這是一個古老的KSH):

read SQL_CONNECT?"Enter your SQL connection string:" 
read n?"Enter number of array elements:" 
# first initialize the array: 
sqlplus -s ${SQL_CONNECT} <<_EOF 
    set serveroutput off 
    set termout off 
    set feedback off 
    begin 
    my_array.init; 
    end; 
/
_EOF 

# then loop on the given number of elements 
typeset -i10 i=0 
while [[ ${i} -lt ${n} ]] 
do 
    i=i+1 
    echo iter:${i} 
    read MY_VALUE?"Enter elements one by one:" 
    sqlplus -s ${SQL_CONNECT} <<_EOF 
    set serveroutput off 
    set termout off 
    set feedback off 
    begin 
    my_array.add(${MY_VALUE}); 
    end; 
/
commit; 
_EOF 
done 

# at the end, use stored values to display result: 
    sqlplus -s ${SQL_CONNECT} <<_EOF 
    set serveroutput on 
    set feedback off 
    begin 
    dbms_output.put_line('---------------'); 
    dbms_output.put_line('your input was:'); 
    my_array.display; 
    end; 
/
_EOF 
+0

另一種解決方案將處理一個SQL腳本的遞歸調用,如在這裏建議:http://stackoverflow.com/a/1873019/ 6019417;但你仍然不能用plsql來完成,而需要使用一個客戶端(這裏也是'sqlplus')。 –