code: int[] executeBatchInternal() throws SQLException
    {
      raiseSQLExceptionIfStatementIsClosed();
  
      SQLException exceptionReturned = null;
      int[] updateCounts = new int[batch.size()];
      batchQueryIDs.clear();
      for (int i = 0; i < batch.size(); i++)
      {
        BatchEntry b = batch.get(i);
        try
        {
          int cnt = this.executeUpdateInternal(
              b.getSql(), b.getParameterBindings(), false);
          if (cnt == NO_UPDATES)
          {
            // in executeBatch we set updateCount to SUCCESS_NO_INFO
            // for successful query with no updates
            cnt = SUCCESS_NO_INFO;
          }
          updateCounts[i] = cnt;
          batchQueryIDs.add(queryID);
        }
        catch (SQLException e)
        {
          exceptionReturned = exceptionReturned == null ? e : exceptionReturned;
          updateCounts[i] = EXECUTE_FAILED;
        }
      }
  
      if (exceptionReturned != null)
      {
        throw new BatchUpdateException(exceptionReturned.getLocalizedMessage(),
                                       exceptionReturned.getSQLState(),
                                       exceptionReturned.getErrorCode(),
                                       updateCounts,
                                       exceptionReturned);
      }
  
      return updateCounts;
    }
docs: This method will iterate through batch and provide sql and bindings to
  underlying SFStatement to get result set.
  <p>
  Note, array binds use a different code path since only one network
  roundtrip in the array bind execution case.
  
  @return the number of updated rows
  @throws SQLException raises if statement is closed or any db error occurs