I'm trying to create a clob from a string of > 4000 chars (supplied in the file_data bind variable) to be used in a Oracle SELECT predicate below:
myQuery=
select *
from dcr_mols
WHERE flexmatch(ctab,:file_data,'MATCH=ALL')=1;
If I add TO_CLOB() round file_data it fails the infamous Oracle 4k limit for a varchar (it's fine for <4k strings). The error (in SQL Developer) is:
ORA-01460: unimplemented or unreasonable conversion requested
01460. 00000 - "unimplemented or unreasonable conversion requested"
FYI The flexmatch function is used for searching molecules , and is a described here : http://help.accelrysonline.com/ulm/onelab/1.0/content/ulm_pdfs/direct/developers/direct_2016_developersguide.pdf
The function itself is a bit complicated but the essence is the 2nd parameter has to be a clob. So my question is how do I convert a Java String bind_variable of over 4000 chars to a clob in sql (or Java).
I tried the method below (which works when inserting clobs) in Java (Spring boot 2) using:
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("file_data", fileDataStr,Types.CLOB);
jdbcNamedParameterTemplate.query(myQuery,parameters,…
This method should work but it fails with a converluted flexmatch error which FYI is:
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"
Note i'm using SpringBoot 2 but I can't get any method using an OracleConnection (obtained from my Spring NamedParametersJdbcTemplate object) to work (even on clobs <4k) , so I suspect i've done something stupid. I've tried:
@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}
Note it works fine if I go old school and use a non spring connection plus a PreparedStatement,which has a setClob() method:
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();
But I would prefer a Spring 2 solution in Java or Sql . Any help, suggestions appreciated.
Stream it. You can't just paste a huge value into a SQL statement.
You'll need to:
INSERT
statement (using EMPTY_BLOB()? ...don't quite remember).This is the standard way of dealing with massive data in Oracle. Plenty of examples out there.
Retrieving massive data (BLOB
and CLOB
types) works the same way. Just use InputStreams in that case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With