update statement preparedstatement prepared parametros los funcionamiento example consultas con java oracle jdbc prepared-statement

java - statement - ¿Dónde está mi personaje inválido(ORA-00911)



preparedstatement java update (2)

Estoy tratando de insertar CLOB s en una base de datos (ver pregunta relacionada ). No puedo entender lo que está mal. Tengo una lista de aproximadamente 85 clobos que quiero insertar en una tabla. Incluso cuando inserto solo la primera clob obtengo ORA-00911: invalid character . No puedo descifrar cómo obtener la declaración de PreparedStatement antes de que se ejecute, por lo que no puedo estar 100% seguro de que sea correcta, pero si lo hice correctamente, debería verse exactamente así:

insert all into domo_queries values (''select substr(to_char(max_data),1,4) as year, substr(to_char(max_data),5,6) as month, max_data from dss_fin_user.acq_dashboard_src_load_success where source = ''''CHQ PeopleSoft FS'''''') select * from dual;

En última instancia, esta instrucción insert all tendría mucho into , por lo que simplemente no hago una instrucción de insert regular. No veo un personaje inválido allí, ¿verdad? (Ah, y ese código anterior funciona bien cuando lo ejecuto en mi herramienta de desarrollador sql ). Y si elimino el punto y coma en PreparedStatement , arroja un error ORA-00933: SQL command not properly ended .

En cualquier caso, aquí está mi código para ejecutar la consulta (y los valores de las variables para el ejemplo anterior).

public ResultSet executeQuery(String connection, String query, QueryParameter... params) throws DataException, SQLException { // query at this point = "insert all //into domo_queries values (?) //select * from dual;" Connection conn = ConnectionPool.getInstance().get(connection); PreparedStatement pstmt = conn.prepareStatement(query); for (int i = 1; i <= params.length; i++) { QueryParameter param = params[i - 1]; switch (param.getType()) { //The type in the example is QueryParameter.CLOB case QueryParameter.CLOB: Clob clob = CLOB.createTemporary(conn, false, oracle.sql.CLOB.DURATION_SESSION); clob.setString(i, "''" + param.getValue() + "''"); //the value of param.getValue() at this point is: /* * select * substr(to_char(max_data),1,4) as year, * substr(to_char(max_data),5,6) as month, * max_data * from dss_fin_user.acq_dashboard_src_load_success * where source = ''''CHQ PeopleSoft FS'''' */ pstmt.setClob(i, clob); break; case QueryParameter.STRING: pstmt.setString(i, "''" + param.getValue() + "''"); break; } } ResultSet rs = pstmt.executeQuery(); //Obviously, this is where the error is thrown conn.commit(); ConnectionPool.getInstance().release(conn); return rs; }

¿Hay algo que me pierda a lo grande?


En lo alto de mi cabeza, ¿puedes intentar usar el operador ''q'' para la cadena literal

algo como

insert all into domo_queries values (q''[select substr(to_char(max_data),1,4) as year, substr(to_char(max_data),5,6) as month, max_data from dss_fin_user.acq_dashboard_src_load_success where source = ''CHQ PeopleSoft FS'']'') select * from dual;

Tenga en cuenta que las comillas simples de su predicado no se escapan, y la cadena se encuentra entre q ''[...]''.


Si usa el literal de cadena exactamente como nos lo ha mostrado, el problema es el ; personaje al final. No puede incluir eso en la cadena de consulta en las llamadas JDBC.

Como está insertando solo una fila, un INSERT regular debería estar bien incluso cuando inserte varias filas. Usar una declaración por lotes es probable que sea más eficiente. No es necesario INSERT ALL . Además, no necesitas el clob temporal y todo eso. Puede simplificar su método a algo como esto (suponiendo que obtuve los parámetros correctos):

String query1 = "select substr(to_char(max_data),1,4) as year, " + "substr(to_char(max_data),5,6) as month, max_data " + "from dss_fin_user.acq_dashboard_src_load_success " + "where source = ''CHQ PeopleSoft FS''"; String query2 = "....."; String sql = "insert into domo_queries (clob_column) values (?)"; PreparedStatement pstmt = con.prepareStatement(sql); StringReader reader = new StringReader(query1); pstmt.setCharacterStream(1, reader, query1.length()); pstmt.addBatch(); reader = new StringReader(query2); pstmt.setCharacterStream(1, reader, query2.length()); pstmt.addBatch(); pstmt.executeBatch(); con.commit();