Ich versuche, aus einer Zeichenfolge von> 4000 Zeichen (in der Bindevariablen file_data enthalten) einen Clob zu erstellen, der in einem der folgenden Oracle SELECT-Prädikate verwendet wird:
myQuery=
select *
from dcr_mols
WHERE flexmatch(ctab,:file_data,'MATCH=ALL')=1;
Wenn ich TO_CLOB () round file_data hinzufüge, verfehlt dies das berüchtigte Oracle 4k-Limit für einen Varchar (es ist in Ordnung für <4k-Strings). Der Fehler (in SQL Developer) ist:
ORA-01460: unimplemented or unreasonable conversion requested
01460. 00000 - "unimplemented or unreasonable conversion requested"
Zu Ihrer Information Die Flexmatch-Funktion wird zum Suchen von Molekülen verwendet und hier beschrieben: http://help.accelrysonline.com/ulm/onelab/1.0/content/ulm_pdfs/direct/developers/direct_2016_developersguide.pdf
Die Funktion selbst ist etwas kompliziert, aber das Wesentliche ist, dass der 2. Parameter ein Clob sein muss. Meine Frage ist also, wie ich eine Java-Zeichenfolge bind_variable mit über 4000 Zeichen in einen Clob in SQL (oder Java) konvertiere.
Ich habe die folgende Methode (die beim Einfügen von Clobs funktioniert) in Java (Spring Boot 2) mit folgenden Methoden ausprobiert:
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("file_data", fileDataStr,Types.CLOB);
jdbcNamedParameterTemplate.query(myQuery,parameters,…
Diese Methode sollte funktionieren, schlägt jedoch mit einem überlasteten Flexmatch-Fehler fehl, der zu Ihrer Information lautet:
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"
Beachten Sie, dass ich SpringBoot 2 verwende, aber mit einer OracleConnection (die von meinem Spring NamedParametersJdbcTemplate-Objekt erhalten wurde) keine Methode zum Arbeiten (auch bei Clobs <4k) erhalten kann. Ich vermute also, dass ich etwas Dummes getan habe. Ich habe es versucht:
@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}
Beachten Sie, dass es gut funktioniert, wenn ich in die alte Schule gehe und eine Nicht-Feder-Verbindung sowie ein PreparedStatement verwende, das eine setClob () -Methode hat:
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();
Aber ich würde eine Spring 2-Lösung in Java oder SQL bevorzugen. Jede Hilfe, Vorschläge geschätzt.
flexmatch()
Funktion hinweisen ? Ich würde gerne die Notwendigkeit dafür sehen. Ehrlich gesagt habe ich in derWHERE
Klausel nie große Werte als Parameter verwendet . Ich habe sie in verwendetINSERT
und ich habe sie mit abgerufenSELECT
. Ihr Fall ist anders.