H2数据库LINK_SCHEMA调用异常:结果集无表且架构找不到
从你贴的代码和后续报错来看,这个问题确实和Oracle JDBC驱动的特性脱不了干系,结合你提到的Evgenij Ryazanov的分析,咱们可以从这几个关键点拆解:
1. 存储过程调用的语法踩坑了
你现在写的SQL语句用了? = CALL这种ODBC风格的写法:
final String query = "? = CALL LINK_SCHEMA('ROADS', '', '" + url + "', '" + user + "', '" + pass + "', 'ROADS');";
但Oracle JDBC驱动对这种写法的支持很有限,尤其是当存储过程要返回结果集时,驱动根本没法正确解析它。Evgenij在讨论里提到,得换成Oracle标准的存储过程调用语法,还要用参数绑定来传值(还能避免SQL注入风险):
final String query = "{ CALL LINK_SCHEMA('ROADS', '', ?, ?, ?, 'ROADS') }"; CallableStatement statement = conn.prepareCall(query); statement.setString(1, url); statement.setString(2, user); statement.setString(3, pass);
2. ResultSet的获取方式不对
Oracle驱动处理存储过程返回的结果集时,不能直接拿statement.getResultSet()就完事。正确的姿势是循环调用getMoreResults()来遍历所有结果集,直到返回false:
boolean hasResults = statement.execute(); while (hasResults) { ResultSet rs = statement.getResultSet(); // 这里处理你的表列表逻辑 hasResults = statement.getMoreResults(); }
因为Oracle存储过程可能会返回多个结果集或者更新计数,直接调用getResultSet()很可能会错过真正包含表列表的那一组结果。
3. 驱动版本拖后腿了
评论区里也提到了,旧版本的Oracle JDBC驱动(比如ojdbc6及更早)对LINK_SCHEMA这种特殊存储过程的支持有bug,没法正确处理跨Schema的元数据链接。建议你升级到最新的稳定版驱动(比如ojdbc11),还要保证驱动版本和你的Oracle数据库版本匹配上。
4. 别忘了权限检查
就算LINK_SCHEMA调用成功了,后续访问表报“Schema not found”,也可能是当前用户没权限访问ROADS这个Schema。得确认执行调用的用户有没有SELECT ANY TABLE权限,或者针对ROADS Schema的特定访问权限。
内容的提问来源于stack exchange,提问作者Roland

