Próbuję utworzyć clob z ciągu> 4000 znaków (podanego w zmiennej powiązania file_data) do użycia w predykacie Oracle SELECT poniżej:
myQuery=
select *
from dcr_mols
WHERE flexmatch(ctab,:file_data,'MATCH=ALL')=1;
Jeśli dodam TO_CLOB () okrągłe dane_pliku, nie powiedzie się niesławny limit Oracle 4k dla varchara (jest w porządku dla <4k ciągów). Błąd (w SQL Developer) to:
ORA-01460: unimplemented or unreasonable conversion requested
01460. 00000 - "unimplemented or unreasonable conversion requested"
FYI Funkcja flexmatch służy do wyszukiwania cząsteczek i jest opisana tutaj: http://help.accelrysonline.com/ulm/onelab/1.0/content/ulm_pdfs/direct/developers/direct_2016_developersguide.pdf
Sama funkcja jest nieco skomplikowana, ale istotą jest to, że drugim parametrem musi być clob. Więc moje pytanie brzmi: jak przekonwertować zmienną wiążącą Java String o wartości ponad 4000 znaków na clob w sql (lub Java).
Wypróbowałem poniższą metodę (która działa podczas wstawiania bloków) w Javie (Spring boot 2), używając:
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("file_data", fileDataStr,Types.CLOB);
jdbcNamedParameterTemplate.query(myQuery,parameters,…
Ta metoda powinna działać, ale kończy się niepowodzeniem z skonwertowanym błędem dopasowania elastycznego, który FYI:
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"
Uwaga: używam SpringBoot 2, ale nie mogę uzyskać żadnej metody przy użyciu OracleConnection (uzyskanej z mojego obiektu Spring NamedParametersJdbcTemplate) do pracy (nawet na blokach <4k), więc podejrzewam, że zrobiłem coś głupiego. Próbowałem:
@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}
Zauważ, że działa dobrze, jeśli pójdę do starej szkoły i użyję nie-sprężynowego połączenia plus PreparedStatement, który ma metodę 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();
Ale wolałbym rozwiązanie Spring 2 w Javie lub Sql. Każda pomoc, sugestie mile widziane.
flexmatch()funkcji? Chciałbym dostrzec potrzebę tego. Szczerze mówiąc, nigdy nie użyłem dużych wartości jako parametrów wWHEREklauzuli. Użyłem ichINSERTi odzyskuję za pomocąSELECT. Twoja sprawa jest inna.