Estoy tratando de crear un clob a partir de una cadena de> 4000 caracteres (suministrados en la variable de enlace file_data) para usar en un predicado de Oracle SELECT a continuación:
myQuery=
select *
from dcr_mols
WHERE flexmatch(ctab,:file_data,'MATCH=ALL')=1;
Si agrego TO_CLOB () round file_data, falla el infame límite de Oracle 4k para un varchar (está bien para <4k cadenas). El error (en SQL Developer) es:
ORA-01460: unimplemented or unreasonable conversion requested
01460. 00000 - "unimplemented or unreasonable conversion requested"
FYI La función flexmatch se usa para buscar moléculas, y se describe aquí: http://help.accelrysonline.com/ulm/onelab/1.0/content/ulm_pdfs/direct/developers/direct_2016_developersguide.pdf
La función en sí es un poco complicada, pero la esencia es que el segundo parámetro tiene que ser un clob. Entonces, mi pregunta es cómo convierto una variable de enlace Java String de más de 4000 caracteres en un clob en sql (o Java).
Probé el siguiente método (que funciona al insertar clobs) en Java (Spring boot 2) usando:
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("file_data", fileDataStr,Types.CLOB);
jdbcNamedParameterTemplate.query(myQuery,parameters,…
Este método debería funcionar, pero falla con un error de coincidencia flexible que FYI es:
SQL state [99999]; error code [29902]; ORA-29902: error in executing ODCIIndexStart() routine\nORA-20100:
MDL-0203: Unable to read from CLOB (csfrm=1, csid=873):
ORA-22922: nonexistent LOB value\nMDL-0021: Unable to copy LOB to string\nMDL-1051: Molstructure search query is not a valid molecule\nMDL-0976:
Molecule index search initialization failed\nORA-06512: at \"C$MDLICHEM80.MDL_MXIXMDL\", line 329\nORA-06512: at \"C$MDLICHEM80.MDL_MXIXMDL\", line 309\n; nested exception is java.sql.SQLException:
ORA-29902: error in executing ODCIIndexStart() routine\nORA-20100: MDL-0203: Unable to read from CLOB (csfrm=1, csid=873):
ORA-22922: nonexistent LOB value\nMDL-0021: Unable to copy LOB to string\nMDL-1051: Molstructure search query is not a valid molecule\nMDL-0976:
Molecule index search initialization failed\nORA-06512: at \"C$MDLICHEM80.MDL_MXIXMDL\", line 329\nORA-06512: at \"C$MDLICHEM80.MDL_MXIXMDL\", line 309\n"
Tenga en cuenta que estoy usando SpringBoot 2 pero no puedo obtener ningún método que use OracleConnection (obtenido de mi objeto Spring NamedParametersJdbcTemplate) para trabajar (incluso en clobs <4k), por lo que sospecho que he hecho algo estúpido. He intentado:
@Autowired
NamedParameterJdbcTemplate jdbcNamedParameterTemplate;
OracleConnection conn = this.jdbcNamedParameterTemplate.getJdbcTemplate().getDataSource().getConnection().unwrap(OracleConnection.class);
Clob myClob = conn.createClob();
myClob.setString( 1, fileDataStr);
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("file_data", myClob,Types.CLOB);
application.properties:
spring.datasource.url=jdbc:oracle:thin:@//${ORA_HOST}:${ORA_PORT}/${ORA_SID}
spring.datasource.username=${ORA_USER}
spring.datasource.password=${ORA_PASS}
Tenga en cuenta que funciona bien si voy a la vieja escuela y uso una conexión que no sea de resorte más un PreparedStatement, que tiene un método setClob ():
OracleDataSource ods = new OracleDataSource();
String url ="jdbc:oracle:thin:@//" + ORA_HOST +":"+ORA_PORT +"/"+ORA_SID;
ods.setURL(url);
ods.setUser(user);
ods.setPassword(passwd);
Connection conn = ods.getConnection();
Clob myClob=conn.createClob();
PreparedStatement ps = conn.prepareStatement("select dcr_number from dcr_mols WHERE flexmatch(ctab,?,'MATCH=ALL')=1");
myClob.setString(1,myMol);
ps.setClob(1,myClob);
ResultSet rs =ps.executeQuery();
Pero preferiría una solución Spring 2 en Java o SQL. Cualquier ayuda, sugerencias apreciadas.
flexmatch()
función? Me gustaría ver la necesidad de esto. Honestamente, nunca usé valores grandes como parámetros en laWHERE
cláusula. Los he usadoINSERT
y los he recuperado usandoSELECT
. Tu caso es diferente.