2014-10-03 2 views
0

Java에서 익명 PLSQL 블록의 결과를 검색하는 데 문제가 있습니다.익명 PLSQL 블록 결과 검색

DECLARE 
in_cnt_date DATE := '&1'; 
hv_cnt_id NUMBER := 0; 
BEGIN 
DBMS_OUTPUT.ENABLE (NULL); 
INSERT INTO dt_contexts 
(CNT_ID, CNT_CONTEXT, CNT_TYPE, CNT_SOURCE, CNT_COMMENT, CNT_DATE, CNT_DATE_INSERT, CNT_DATE_UPDATE) 
VALUES 
(0, 'EPE_CONTEXT', 'ROUTE', 'bdd', 'Built from ROUTE', in_cnt_date, SYSDATE, SYSDATE); 

SELECT SEQ_DT_CNT_ID.CURRVAL 
INTO hv_cnt_id 
FROM DUAL; 
EXCEPTION WHEN OTHERS THEN RAISE ; 
END; 

내가 문자열에서 해당 쿼리를 넣어 :

public static final String CONTEXT = "DECLARE in_cnt__date DATE := '&1'; " + 
"hv_cnt_id NUMBER := 0; " + 
"BEGIN DBMS_OUTPUT.ENABLE (NULL); " + 
"INSERT INTO dt_contexts (CNT_ID, CNT_CONTEXT, CNT_TYPE, CNT_SOURCE, CNT_COMMENT, CNT_DATE, CNT_DATE_INSERT, CNT_DATE_UPDATE) " + 
"VALUES (0, 'EPE_CONTEXT', 'ROUTE', 'bdd', 'Built from ROUTE', ?, SYSDATE, SYSDATE); " + 
"SELECT SEQ_DT_CNT_ID.CURRVAL INTO hv_cnt_id FROM DUAL; " + 
"EXCEPTION WHEN OTHERS THEN RAISE ; END;"; 

그 문자열이 정확 여기

블록입니까? hv_cnt_id를 검색하려고

방법 :

java.sql.SQLException: ORA-01858: a non-numeric character was found where a numeric was expected ORA-06512: at line 1

그래서 어떻게 hv_cnt_id를 검색 할 :

public int getContextId(Connection conn) throws Exception { 
    CallableStatement cs = null; 
    ResultSet rs = null; 
    int contextId = 0; 
    try { 
     conn.setAutoCommit(false); 
     cs = conn.prepareCall(CONTEXT); 
     cs.setDate(1, (java.sql.Date) Route.datePrf); 

     cs.execute(); 
     contextId = (Integer) cs.getObject(1); 

     conn.commit(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     throw e; 
    } finally { 
     close(rs, cs); 
    } 
    return contextId; 
} 

은 내가이 메시지가 같은 일을 does'nt?

+0

모든 예외 핸들러를 제거하고 실행하여 PL/SQL 블록에 추가 블록 및 yiu는 오류가 발생한 정확한 행 번호를 보게됩니다. –

+0

암시적인 날짜 변환이 실패하기 때문입니다. 직접 날짜 문자열을 날짜 변수에 할당하는 대신에'TO_DATE()'를 추가하십시오. 암시 적 변환은 대개 세션의'NLS_DATE_FORMAT'에 달려 있습니다. –

+0

익명 블록에 매개 변수를 전달하려고하는 것처럼 보입니다. 불가능하다고 생각합니다. – mustaccio

답변

3

암시 적 날짜 변환에 실패했기 때문입니다. 직접 날짜 문자열을 날짜 변수에 할당하는 대신 TO_DATE()을 추가하십시오. java.sql.Date을 사용하는 경우 TO_DATE()은 필요하지 않습니다.

암시 적 변환은 일반적으로 세션의 NLS_DATE_FORMAT에 따라 다릅니다.

귀하의 경우에는 in_cnt__date DATE := '&1'이 범인입니다. &1 실제로 날짜로 변환하려고 시도합니다 .. 따라서 예외가 발생했습니다!

public static final String CONTEXT = "DECLARE in_cnt__date DATE := ? ;" + 
"hv_cnt_id NUMBER := 0; " + 
"BEGIN DBMS_OUTPUT.ENABLE (NULL); " + 
"INSERT INTO dt_contexts (CNT_ID, CNT_CONTEXT, CNT_TYPE, CNT_SOURCE, CNT_COMMENT, CNT_DATE, CNT_DATE_INSERT, CNT_DATE_UPDATE) " + 
"VALUES (0, 'EPE_CONTEXT', 'ROUTE', 'bdd', 'Built from ROUTE', in_cnt__date, SYSDATE, SYSDATE); " + 
"SELECT SEQ_DT_CNT_ID.CURRVAL INTO hv_cnt_id FROM DUAL; " + 
"? := hv_cnt_id; 
"EXCEPTION WHEN OTHERS THEN RAISE ; END;"; 

그리고,

cs.setDate(1, (java.sql.Date) Route.datePrf); 

in_cnt__date의 날짜를 설정합니다;

마지막으로, hv_cnt_id 아래에있는 값을 retreive하기는

"? := hv_cnt_id;" 

그리고 JDBC에서, 우리는 같은 그것을 얻을

,

cs.setDate(1, (java.sql.Date) Route.datePrf); 
cs.registerOutParameter(2, Types.NUMBER); 
cs.execute(); 
contextId = cs.getInt(2); 
+0

인덱스가 잘못되었지만 왜 그렇지 않은 것입니까 :'contextId = cs.getInt (2);'? –

+0

예 알렉스, 네 말이 맞아. 방금 OP의 동일한 코드를 사용했습니다. –

0

PL/SQL 코드에서 exception 핸들러를 모두 제거하고 블록을 실행하면 오류가 발생한 정확한 행 번호가 표시됩니다.

Raise 내부는 예외로 정확한 오류 정보을 알 수 없습니다. RAISE 부분을 중심으로 http://lalitkumarb.wordpress.com/2014/05/02/when-others-then-null-a-bug/을 (를) 읽으십시오.

일단 수정하면 data type 변환 문제가 있음을 알 수 있습니다.