【问题标题】:In JDBC, when executing multiple statements - how to know for each ResultSet to which statement does it belong to?在 JDBC 中,当执行多个语句时 - 如何知道每个 ResultSet 属于哪个语句?
【发布时间】:2021-07-06 14:24:54
【问题描述】:

让我们假设以下 JDBC 中的虚拟示例:

   Statement statement = connection.createStatement();
   statement.execute("select * from X; call sp1(); select * from Y; call sp2(); select * Z");
   
   int uc = statement .getUpdateCount();
   boolean isResult = (uc == -1);

   do
   {
      if( isResult )
      {
         ResultSet rs = statement.getResultSet();

         if( rs != null )
         {
            doSomethingWithRS( rs );
         }
      }
      else
      {
         System.out.println( "update count: " + uc );
      }
   }
   while( ( isResult = statement.getMoreResults() ) || ( uc = statement.getUpdateCount() ) != -1 );

众所周知,某些数据库/驱动程序允许执行多条语句(以 SQL Server 为例)。请注意,有 5 条语句在数据库端一一执行。驱动程序发出未知数量的结果集。这是因为存储过程可能会返回任意数量的结果集,具体取决于它们的内部结构。

对于每个检索到的结果集,有什么方法可以识别它属于哪个特定语句?

注意,我发布了另一个question,重点是确定可能回答主题中问题的存储过程信息。不过,我希望 JDBC 本身可能有办法解决这个问题。

【问题讨论】:

    标签: stored-procedures jdbc


    【解决方案1】:

    JDBC 中没有任何内容可以确定存储过程中的哪个语句产生了结果集。就 JDBC 而言,只有一条语句,即您为执行存储过程而执行的语句。该存储过程内部发生的事情对 JDBC 来说是一个黑盒。

    对于您发布的特定示例,更合适的方法是单独执行这些语句。 JDBC 的期望是您一次执行一条语句。 SQL Server 允许您像这样执行由分号分隔的多个语句的事实,从正式的 JDBC 角度来看是可疑的,但 SQL Server/T-SQL 将其作为一种“匿名过程”处理(就好像这是一个存储的过程,并且您执行了该单个存储过程)。

    理论上,特定驱动程序可能具有 JDBC 规范中定义的功能之外的功能,但考虑到数据库及其协议通常如何工作,如果实际情况确实如此,我会感到惊讶。

    协议通常很简单,没有多余的装饰,因为我想必须确切知道存储过程内部中的哪个语句产生了哪个结果集1,并为此按照“result: update count = 1”“result: result set”(后跟行)等方式进行交流。

    如果您确实需要知道存储过程的哪个语句产生了哪个结果集,那么您将需要重新考虑您在做什么,而不是使用产生多个结果的存储过程,而是从您的 Java 应用程序中驱动它(单独执行它们),或者只编写具有确定性结果的存储过程(例如,总是以完全相同的顺序产生 n 个结果),或者在结果中添加一个额外的列以明确提供标识。


    1:或者至少,我真的想不出与此信息相关的实际情况(可能用于调试除外)。此外,这会将调用代码与存储过程的确切和文字实现紧密耦合(考虑如果语句文本更改会发生什么)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      • 2014-03-15
      • 2014-12-28
      • 2011-08-26
      • 1970-01-01
      • 1970-01-01
      • 2014-02-11
      相关资源
      最近更新 更多