我在检索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:
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()则不需要。
TO_DATE()
java.sql.Date
隐式转换通常取决于会话的NLS_DATE_FORMAT。
NLS_DATE_FORMAT
您in_cnt__date DATE := '&1'的罪魁祸首。&1实际上将尝试转换为日期。因此引发了异常!
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;
in_cnt__date
最后,要获取以下内容中的值,hv_cnt_id 以下内容将添加到您的代码PL/SQL块中
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);