无法使用sqljdbc4.jar在Java中为Prepared-和CallableStatement获取SQL执行计划

时间:2016-07-29 10:50:20

标签: java sql-server jdbc

我们最近实施了Microsoft Type 4 JDBC驱动程序(适用于SQL Server的Microsoft JDBC驱动程序4.2的sqljdbc4.jar),支持jTDS。当我们尝试从Java代码中检索Callable和PreparedStatement对象的估计和实际执行计划时,我们现在遇到了问题。 我能找到的唯一领导是: Get the query plan using jdbc PreparedStatement on sql server 但尚未提供具体答案。 该数据库是SQL Server 2008R2。 示例代码是:

Connection cn          = null;
PreparedStatement stmt = null;
Statement execplan_stmt = null;
ResultSet rs           = null;
try
{
    cn = getConnection();

    execplan_stmt = cn.createStatement();
    execplan_stmt.executeUpdate("SET SHOWPLAN_XML ON");
    stmt = cn.prepareStatement("SELECT value FROM cfg_system_properties WHERE 
                                property = ?"); 
    stmt.execute();
    rs = stmt.getResultSet();
    while(rs != null && rs.next())
    {
        Object obj = rs.getObject(1);
        System.out.println("Query plan {} " + obj);
   }
   execplan_stmt.execute("SET SHOWPLAN_XML OFF");          

}
catch (SQLException e)
{
    e.printStackTrace();
}

即使更换

while(rs != null && rs.next()) 

的循环语句
if(rs.next())
{
    String exec_plan = rs.getString(1);
}

不起作用,因为rs.next()为false。 在这个例子中,sql包含一个占位符字符'?',它首先导致“java.sql.SQLException:参数#1尚未设置”。错误,这是不需要的。我不想执行查询,我想获得执行计划,无论是实际的还是估计的查询计划。 用实际值替换占位符不会再破坏占位符,但不会返回执行计划。 激活SQL事件探查器表示应该返回执行计划,但是当链接文章正确指出时,似乎返回实际结果而不是执行计划。 司机是否可能抛弃执行计划? 在获取需要设置的数据库连接时是否需要设置任何特定配置才能执行此操作? 有人成功地完成了这个吗?

1 个答案:

答案 0 :(得分:0)

SQL Server不会返回执行预准备语句的估计执行计划。 jTDS有一个执行Java PreparedStatement的怪癖,更像是简单的Statement,导致SQL Server返回一个估计的执行计划。 MS驱动程序没有这个怪癖,因此在执行Java Prepared-或CallableStatement时不会返回估计的执行计划。使用jTDS时,可能会返回估计的执行计划,但不保证所有PreparedStatement都可以。