2013-10-25 45 views
0

我試圖通過java調用我的oracle 11g pl/sql包它會報錯。請幫幫我。 這是關於pl/sql程序,java程序和Java錯誤的所有信息。如何調用我的程序編譯錯誤發生在java

過程成功創建和sql查詢都經過測試。

/* 
    * create package called "final_package" 
    * create PROCEDURE called "final_procedure" 
    * var1 is input parameter from application 
    * dbinfo is out parameter to application 
    */ 
    CREATE OR REPLACE PACKAGE final_package as 
     PROCEDURE final_procedure(var1 in varchar2, dbinfo out varchar2); 
     END final_package;           
     /
    CREATE OR REPLACE PACKAGE BODY final_package IS  
     PROCEDURE final_procedure(var1 in varchar2, dbinfo out varchar2) IS 
    BEGIN 
     IF var1 = 'a' --input variable checking-- 

    ------ /* get tablespaces name, percentage */ ---- 
THEN 
DECLARE 

tsname varchar2(500); ---- /* put tablespaces name to this tsinfo */---- 
percentage varchar2(500); ---- /* put tablespaces percentage to this tsinfo */---- 

--declare cursor tbspinfo-- 
CURSOR tbspinfo is select a.TABLESPACE_NAME as 
    Tablespace,round((1-((a.BYTES-nvl(b.BYTES,0))/a.BYTES))*100,2) 
    AS 
    Percentages from (select TABLESPACE_NAME, sum(BYTES) BYTES from 
    sys.dba_data_files group by TABLESPACE_NAME) a, 
    (select 
    TABLESPACE_NAME, sum(BYTES) BYTES from sys.dba_free_space 
    group by 
    TABLESPACE_NAME) b 
    where 
    a.TABLESPACE_NAME = b.TABLESPACE_NAME (+) 
    order by ((a.BYTES-b.BYTES)/a.BYTES) desc; 


BEGIN 
FOR each_data1 in tbspinfo 
LOOP 
-- FETCH tsname,percentage INTO tsinfo --- 
    FETCH tbspinfo INTO tsname, percentage; 
-- add tsinfo INTO out parameter "dbinfo" --- 
    dbinfo := tsname || percentage; 
    END LOOP; 
    CLOSE tbspinfo; 

END; 
---- /* get database lock status */ ---- 
ELSIF var1 = 'b' THEN 
DECLARE 
locking_id varchar2(1500); 
waiting_id varchar2(1500); 
status varchar2(150); 
program_hold varchar2(300); 
program_wait varchar2(300); 

--declare cursor lock_info-- 
CURSOR lock_info is SELECT vh.sid locking_sid, 
vw.sid waiter_sid, 
vs.status status, 
vs.program program_holding, 
vsw.program program_waiting 
FROM v$lock vh, 
v$lock vw, 
v$session vs, 
v$session vsw 
WHERE(vh.id1, vh.id2) IN (SELECT id1, id2 
FROM v$lock 
WHERE request = 0 
INTERSECT 
SELECT id1, id2 
FROM v$lock 
WHERE lmode = 0) 
AND vh.id1 = vw.id1 
AND vh.id2 = vw.id2 
AND vh.request = 0 
AND vw.lmode = 0 
AND vh.sid = vs.sid 
AND vw.sid = vsw.sid; 
    BEGIN 
FOR each_data in lock_info 
LOOP 
-- /* put database lock_info to varchar2 variables "locking_id,waiting_id,status,program_hold,program_wait" */ -- 
    FETCH lock_info INTO locking_id,waiting_id,status,program_hold,program_wait; 
    END LOOP; 
    CLOSE lock_info; 

    -- /* add lock_info INTO out parameter "dbinfo" */ --- 
    dbinfo := locking_id || waiting_id || status || program_hold || program_wait; 

END; 

    END IF; 
    END; 

    END; 
/

java代碼是

CallableStatement clbstmt = con.prepareCall("BEGIN final_package.final_procedure(?,?); END;"); 
      clbstmt.setString(1, var1); 
      clbstmt.registerOutParameter(2, OracleTypes.VARCHAR); 
      clbstmt.execute(); // error comes at this 
      abc = clbstmt.getNString(Integer.SIZE); 
      abb = clbstmt.getNString(Integer.SIZE); 

Java錯誤是

SEVERE: null 
java.sql.SQLException: ORA-01001: invalid cursor 
ORA-06512: at "SYS.FINAL_PACKAGE", line 71 
+0

說明您的問題簡單?把所需的代碼和java stacktrace?如果不知道問題,你的整個程序代碼就沒有意義了? java錯誤/代碼鏈接不起作用 –

+0

你的'con.prepareCall'有問題。只需放入package.procedurename,它將調用所需的過程。你不需要添加'BEGIN'和'END'。 – Rachcha

+0

@ Rachcha我檢查並更改,但錯誤是一樣的。我認爲程序錯誤。我對pl/sql代碼做了一點點評論,請幫助我 –

回答

0

該過程的此片段是錯誤的:

FOR each_data IN lock_info 
LOOP 
-- put database lock_info to varchar2 variables "locking_id,waiting_id,status,program_hold,program_wait" -- 
    FETCH lock_info INTO locking_id,waiting_id,status,program_hold,program_wait; 
END LOOP; 
CLOSE lock_info; 

使用隱式遊標FOR LOOP語句時,請勿使用FETCHCLOSE cursor
遊標for循環語句打開遊標,爲每次迭代(每行)將行提取到記錄變量中,然後自行關閉遊標。您不能關閉光標,因爲它已經關閉。
查看詳細鏈接:http://docs.oracle.com/cd/E11882_01/appdev.112/e17126/static.htm#CHDBJBJE

該代碼的另一個問題是,它從循環中的遊標中獲取值,但不處理它們。這沒有意義。當代碼離開循環時,變量不確定 - 它們具有隨機值。在循環中獲取數據時,代碼必須在此循環中處理獲取的數據。

改變此密碼爲:

FOR each_data IN lock_info 
LOOP 
-- FETCH lock_info INTO locking_id,waiting_id,status,program_hold,program_wait; 
    locking_id := each_data.locking_id; 
    waiting_id := each_data.waiting_id; 
    status := each_data.status; 
    program_hold := each_data.program_hold; 
    program_wait := each_data.program_wait; 

    -- Process fetched data here 

END LOOP; 
-- CLOSE lock_info; 

或者您可以使用顯式遊標循環:

OPEN lock_info; 
LOOP 
    FETCH lock_info INTO locking_id,waiting_id,status,program_hold,program_wait; 
    EXIT WHEN lock_info%NOTFOUND; 

    -- Process fetched data here 

END LOOP; 
CLOSE lock_info; 
+0

@ kordirko先生,我做了如上所述的更改,但是現在我得到一個錯誤''LINE/COL ERROR 32/4 PL/SQL:Statement ignored 32/24 PLS -00302:必須聲明組件'TSNAME' PLS-00302:必須聲明組件'PERCENTAGE' PL/SQL:忽略語句 75/30 PLS-00302:必須聲明組件'LOCKING_ID' 76/6 PL/SQL:語句被忽略 76/30 PLS-00302:必須聲明組件'WAITING_ID' PLS-00302:組件'PROGRAM_WAIT'必須聲明爲''但我已經聲明它們高於代碼請幫助我請 –

+0

確定它的工作原理沒有聲明需要謝謝你支持我,並建議感謝很多 –