Я намагаюся створити клоб із рядка> 4000 знаків (надається у змінній файлу файлу_даних), який буде використаний у предикаті Oracle SELECT нижче:
myQuery=
select *
from dcr_mols
WHERE flexmatch(ctab,:file_data,'MATCH=ALL')=1;
Якщо я додаю TO_CLOB () круглий file_data, це не відповідає сумнозвісному обмеженню Oracle 4k для varchar (це добре для <4k рядків). Помилка (у SQL Developer):
ORA-01460: unimplemented or unreasonable conversion requested
01460. 00000 - "unimplemented or unreasonable conversion requested"
FYI Функція flexmatch використовується для пошуку молекул і описується тут: http://help.accelrysonline.com/ulm/onelab/1.0/content/ulm_pdfs/direct/developers/direct_2016_developersguide.pdf
Сама функція трохи складна, але суть у тому, що другий параметр повинен бути клобом. Отже, моє запитання полягає в тому, як перетворити Java-рядок bind_variable з понад 4000 символів у clob в sql (або Java).
Я спробував метод нижче (який працює при вставці клопів) в Java (Spring boot 2), використовуючи:
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("file_data", fileDataStr,Types.CLOB);
jdbcNamedParameterTemplate.query(myQuery,parameters,…
Цей метод повинен працювати, але він не вдається зі збіжною помилкою flexmatch, яка є 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"
Зауважте, що я використовую SpringBoot 2, але я не можу отримати жодного методу за допомогою OracleConnection (отриманого від мого об'єкта Spring NamedParametersJdbcTemplate) для роботи (навіть на clobs <4k), тому я підозрюю, що я зробив щось дурне. Я спробував:
@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}
Зверніть увагу, що це добре працює, якщо я переходжу в стару школу і використовую непідпрудне з'єднання плюс PreparedStatement, у якому є метод 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();
Але я вважаю за краще рішення Spring 2 на Java або Sql. Будь-яка допомога, пропозиції високо оцінені.
flexmatch()
функції? Я хотів би бачити потребу в цьому. Чесно кажучи, я ніколи не використовував великі значення як параметри вWHERE
пункті. Я використовував їх,INSERT
і я їх отримував за допомогоюSELECT
. Ваш випадок інший.