【问题标题】:Determine if a Statement/ResultSet are using a Table before a Statement Query?确定语句/结果集是否在语句查询之前使用表?
【发布时间】:2016-09-09 22:31:39
【问题描述】:

这是我正在使用的场景:我有一个 ResultSet 对象,它正在使用我的 SQL 数据库中的某个表。我正在从事的项目非常大,我已经跟踪了 SQL Statements,它们应该被关闭。

但是,当我尝试在有问题的特定表上执行 Statement 时,我收到以下错误:

SQLException caught in Error Executing SQL statement :Operation 'ALTER TABLE' cannot be performed on object 'CONNECTIONS' because there is an open ResultSet dependent on that object.

在我查询表检查之前有什么方法可以确定 如果ResultSet/Statement 对象正在使用有问题的表,在这种情况下是表“CONNECTIONS”,然后使用java.sql 中的可用对象获取ResultSet/Statement 对象并关闭它我可以执行我的声明吗?

【问题讨论】:

  • 您是否可以访问整个项目的源代码?在这种情况下,进行大量搜索以查找字符串“连接”是否有用?
  • 从来没有任何硬编码的“连接”语句可以改变。例如,在尝试为它更改表时,另一个名为“INPUTS”的表上可能会出现同样的问题。如果这有意义吗? @LittleSanti

标签: java sql


【解决方案1】:

您可以监视在客户端代码和实际驱动程序之间插入您自己的 JDBC 驱动程序的每个执行的语句。有些工作要做,但在概念上很简单:

  1. 您必须通过实现java.sql.Driverjava.sql.Connectionjava.sql.Statement(在这种情况下无需实现 ResultSet)来实现自己的 JDBC 驱动程序作为委托给实际驱动程序。嘿,不要颤抖:你不必一一编写所有的 JDBC 方法;实际上,为每个接口实例化一个动态代理就足够了。

  2. 动态代理必须简单地委托给目标对象。并且对于Statement.executeQuery()Connection.prepareStatement()Connection.prepareCall() 方法有一个特殊的行为:每当调用这些方法中的任何一个时,您应该获取第一个参数(它是一个包含SQL 语句的字符串)并解析它以查找目标表名称(在您的示例“连接”中)。根据所需的准确性,您应该进行完整、严格的 SQL 解析,或者您可以通过 String.indexOf(...) 进行简单的子字符串搜索。

  3. 当解析结果为正时,由您决定:您可以将完整的当前堆栈跟踪溢出到控制台(以便您可以在之后对其进行处理以修复客户端类),或者存储源 Statement 对象到可访问的对象存储(可能是单例映射),以便您可以从代码中的另一个点关闭它...

  4. 最后一个细节是如何用您自己的“间谍”驱动程序替换实际驱动程序。很简单:只需让您的驱动程序识别一种特殊类型的 JDBC URL(例如 jdbc:my-spy-driver:thin:@localhost:port:etc),然后让客户端代码使用该 URL。

请注意,使用这种驱动程序会降低性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-14
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 2015-03-20
    • 1970-01-01
    • 2014-09-04
    相关资源
    最近更新 更多