J'essaie de créer un clob à partir d'une chaîne de> 4000 caractères (fourni dans la variable de liaison file_data) à utiliser dans un prédicat Oracle SELECT ci-dessous:
myQuery=
select *
from dcr_mols
WHERE flexmatch(ctab,:file_data,'MATCH=ALL')=1;
Si j'ajoute TO_CLOB () autour de file_data, il échoue à la fameuse limite Oracle 4k pour un varchar (c'est bien pour <4k strings). L'erreur (dans SQL Developer) est:
ORA-01460: unimplemented or unreasonable conversion requested
01460. 00000 - "unimplemented or unreasonable conversion requested"
Pour info La fonction flexmatch est utilisée pour rechercher des molécules et est décrite ici: http://help.accelrysonline.com/ulm/onelab/1.0/content/ulm_pdfs/direct/developers/direct_2016_developersguide.pdf
La fonction elle-même est un peu compliquée mais l'essentiel est que le 2ème paramètre doit être un clob. Donc, ma question est de savoir comment convertir une chaîne Java bind_variable de plus de 4000 caractères en un clob en sql (ou Java).
J'ai essayé la méthode ci-dessous (qui fonctionne lors de l'insertion de clobs) en Java (Spring boot 2) en utilisant:
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("file_data", fileDataStr,Types.CLOB);
jdbcNamedParameterTemplate.query(myQuery,parameters,…
Cette méthode devrait fonctionner, mais elle échoue avec une erreur de flexmatch convergée dont FYI est:
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"
Notez que j'utilise SpringBoot 2 mais je ne peux obtenir aucune méthode utilisant un OracleConnection (obtenu à partir de mon objet Spring NamedParametersJdbcTemplate) pour travailler (même sur des clobs <4k), donc je soupçonne que j'ai fait quelque chose de stupide. J'ai essayé:
@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}
Notez que cela fonctionne bien si je vais à l'ancienne et que j'utilise une connexion sans ressort plus un PreparedStatement, qui a une méthode 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();
Mais je préférerais une solution Spring 2 en Java ou Sql. Toute aide, suggestions appréciées.
flexmatch()
fonction? J'aimerais voir la nécessité de cela. Honnêtement, je n'ai jamais utilisé de grandes valeurs comme paramètres dans laWHERE
clause. Je les ai utilisésINSERT
et je les ai récupérés en utilisantSELECT
. Votre cas est différent.