检索匿名PLSQL块结果

我在java中检索匿名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的方法:

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

它没有用,因为我得到这个消息:

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

那么如何检索hv_cnt_id呢?

这是因为隐式日期转换失败了。 添加TO_DATE()而不是直接将日期字符串分配给日期变量。 如果使用java.sql.Date ,则不需要TO_DATE()

隐式转换通常取决于会话的NLS_DATE_FORMAT

在你的情况下in_cnt__date DATE := '&1'是罪魁祸首。 &1实际上将被尝试转换为日期..因此抛出exception!

 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的值,以下内容将添加到PL/SQL块中

 "? := hv_cnt_id;" 

从JDBC,我们得到它,

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

PL/SQL代码中删除所有exception处理程序,并执行该块,您将看到发生错误的确切行号。

Raise内部exception永远不会让您知道确切的错误细节 。 请阅读http://lalitkumarb.wordpress.com/2014/05/02/when-others-then-null-a-bug/关注RAISE部分。

完成后,您会发现存在data type转换问题。