检索匿名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
转换问题。
- 在Java中写长和双是不是primefaces的?
- 使用Groovy(或Java)如何将org.joda.time.LocalDateTime转换为java.util.date?
- Apache Kafka和Avro:org.apache.avro.generic.GenericData $ Record无法强制转换为com.harmeetsingh13.java.Customer
- 组件系列,组件类型和渲染器类型之间的关系是什么?
- java swing:为JTree项添加自定义图形按钮
- 如何使用EasyMock测试void方法
- 窗户上的虚假唤醒。 可能吗?
- 为什么将null转换为Object?
- Java内存行为:与Thread.sleep不同