我正在尝试从> 4000个字符(在file_data绑定变量中提供)的字符串创建一个Clob,以在下面的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"
仅供参考,flexmatch函数用于搜索分子,在此处进行了描述:http : //help.accelrysonline.com/ulm/onelab/1.0/content/ulm_pdfs/direct/developers/direct_2016_developersguide.pdf
函数本身有点复杂,但本质是第二个参数必须是Clob。所以我的问题是如何将超过4000个字符的Java字符串bind_variable转换为sql(或Java)中的clob。
我使用以下方法在Java(Spring boot 2)中尝试了以下方法(在插入Clob时有效):
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("file_data", fileDataStr,Types.CLOB);
jdbcNamedParameterTemplate.query(myQuery,parameters,…
此方法应该可以工作,但是会失败,并会产生一个弹性匹配错误,仅供参考:
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对象获得)来工作(即使是在<4k的Clob上),所以我怀疑我做了一些愚蠢的事情。我试过了:
@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}
请注意,如果我去上学,并使用非弹簧连接加上带有setClob()方法的PreparedStatement,它会很好地工作:
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();
但是我更喜欢Java或Sql的Spring 2解决方案。任何帮助,建议表示赞赏。
flexmatch()
函数的API文档吗?我希望看到这一点。老实说,我从没在WHERE
子句中使用大值作为参数。我已在中使用它们,INSERT
并已使用检索它们SELECT
。您的情况不同。