예제 #1
0
  /**
   * Helper method that derived classes may use to set warnings
   *
   * @param warning Warning
   */
  protected void setWarning(SQLWarning warning) {
    LOGGER.warn("SQL Warning was issued", warning);

    if (this.warnings == null) {
      this.warnings = warning;
    } else {
      // Chain with existing warnings
      warning.setNextWarning(this.warnings);
      this.warnings = warning;
    }
  }
예제 #2
0
 protected void setWarning(SQLWarning warn) {
   if (warnings == null) warnings = warn;
   else warnings.setNextWarning(warn);
   return;
 }
 /** Adds an SQLWarning to the warning chain. */
 synchronized void addWarning(SQLWarning warn) {
   if (warnings == null) warnings = warn;
   else warnings.setNextWarning(warn);
 }
  /**
   * Create a new scrollable result set in memory or a named server cursor.
   *
   * @param sql The SQL SELECT statement.
   * @param procName Optional procedure name for cursors based on a stored procedure.
   * @param parameters Optional stored procedure parameters.
   * @exception java.sql.SQLException
   */
  private void cursorCreate(String sql, String procName, ParamInfo[] parameters)
      throws SQLException {
    //
    boolean isSelect = false;
    SQLWarning warning = null;
    //
    // Validate the SQL statement to ensure we have a select.
    //
    if (resultSetType != ResultSet.TYPE_FORWARD_ONLY
        || concurrency == ResultSet.CONCUR_UPDATABLE
        || cursorName != null) {
      //
      // We are going to need access to a SELECT statement for
      // this to work. Reparse the SQL now and check.
      //
      ArrayList params = new ArrayList();
      String tmp[] =
          new SQLParser(sql, params, (ConnectionJDBC2) statement.getConnection()).parse(true);

      if (tmp[2].equals("select") && tmp[3] != null && tmp[3].length() > 0) {
        // OK We have a select with at least one table.
        tableName = tmp[3];
        isSelect = true;
      } else {
        // No good we can't update and we can't declare a cursor
        cursorName = null;
        if (concurrency == ResultSet.CONCUR_UPDATABLE) {
          concurrency = ResultSet.CONCUR_READ_ONLY;
          warning =
              new SQLWarning(Messages.get("warning.cursordowngraded", "CONCUR_READ_ONLY"), "01000");
        }
        if (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE) {
          resultSetType = ResultSet.TYPE_SCROLL_INSENSITIVE;
          SQLWarning warning2 =
              new SQLWarning(
                  Messages.get("warning.cursordowngraded", "TYPE_SCROLL_INSENSITIVE"), "01000");
          if (warning != null) {
            warning.setNextWarning(warning2);
          } else {
            warning = warning2;
          }
        }
      }
    }
    //
    // If a cursor name is specified we try and declare a conventional cursor
    //
    if (cursorName != null) {
      //
      // We need to substitute any parameters now as the prepended DECLARE CURSOR
      // will throw the parameter positions off.
      //
      if (parameters != null && parameters.length > 0) {
        sql = Support.substituteParameters(sql, parameters, statement.getTds().getTdsVersion());
      }
      StringBuffer cursorSQL = new StringBuffer(sql.length() + cursorName.length() + 128);
      cursorSQL.append("DECLARE ").append(cursorName).append(" CURSOR FOR ").append(sql);
      cursorTds.executeSQL(
          cursorSQL.toString(),
          procName,
          parameters,
          false,
          statement.getQueryTimeout(),
          statement.getMaxRows(),
          statement.getMaxFieldSize(),
          true);
      cursorTds.clearResponseQueue();
      cursorSQL.setLength(0);
      cursorSQL.append("\r\nOPEN ").append(cursorName);
      if (fetchSize > 1 && isSybase) {
        cursorSQL.append("\r\nSET CURSOR ROWS ").append(fetchSize);
        cursorSQL.append(" FOR ").append(cursorName);
      }
      cursorSQL.append("\r\nFETCH ").append(cursorName);
      //
      // OK Declare cursor, open it and fetch first (fetchSize) rows.
      //
      cursorTds.executeSQL(
          cursorSQL.toString(),
          null,
          null,
          false,
          statement.getQueryTimeout(),
          statement.getMaxRows(),
          statement.getMaxFieldSize(),
          true);

      while (!cursorTds.getMoreResults() && !cursorTds.isEndOfResponse()) ;

      if (!cursorTds.isResultSet()) {
        throw new SQLException(Messages.get("error.statement.noresult"), "24000");
      }
      columns = cursorTds.getColumns();
      columnCount = getColumnCount(columns);
    } else {
      //
      // Open a memory cached scrollable or forward only possibly updateable cursor
      //
      if (isSelect
          && (concurrency == ResultSet.CONCUR_UPDATABLE
              || resultSetType != ResultSet.TYPE_FORWARD_ONLY)) {
        // Need to execute SELECT .. FOR BROWSE to get
        // the MetaData we require for updates etc
        // OK Should have an SQL select statement
        // append " FOR BROWSE" to obtain table names
        // NB. We can't use any jTDS temporary stored proc
        cursorTds.executeSQL(
            sql + " FOR BROWSE",
            null,
            parameters,
            false,
            statement.getQueryTimeout(),
            statement.getMaxRows(),
            statement.getMaxFieldSize(),
            true);
        while (!cursorTds.getMoreResults() && !cursorTds.isEndOfResponse()) ;
        if (!cursorTds.isResultSet()) {
          throw new SQLException(Messages.get("error.statement.noresult"), "24000");
        }
        columns = cursorTds.getColumns();
        columnCount = getColumnCount(columns);
        rowData = new ArrayList(INITIAL_ROW_COUNT);
        //
        // Load result set into buffer
        //
        while (super.next()) {
          rowData.add(copyRow(currentRow));
        }
        rowsInResult = rowData.size();
        initialRowCnt = rowsInResult;
        pos = POS_BEFORE_FIRST;
        //
        // If cursor is built over one table and the table has
        // key columns then the result set is updateable and / or
        // can be used as a scroll sensitive result set.
        //
        if (!isCursorUpdateable()) {
          // No so downgrade
          if (concurrency == ResultSet.CONCUR_UPDATABLE) {
            concurrency = ResultSet.CONCUR_READ_ONLY;
            statement.addWarning(
                new SQLWarning(
                    Messages.get("warning.cursordowngraded", "CONCUR_READ_ONLY"), "01000"));
          }
          if (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE) {
            resultSetType = ResultSet.TYPE_SCROLL_INSENSITIVE;
            statement.addWarning(
                new SQLWarning(
                    Messages.get("warning.cursordowngraded", "TYPE_SCROLL_INSENSITIVE"), "01000"));
          }
        }
        return;
      }
      //
      // Create a read only cursor using direct SQL
      //
      cursorTds.executeSQL(
          sql,
          procName,
          parameters,
          false,
          statement.getQueryTimeout(),
          statement.getMaxRows(),
          statement.getMaxFieldSize(),
          true);
      while (!cursorTds.getMoreResults() && !cursorTds.isEndOfResponse()) ;

      if (!cursorTds.isResultSet()) {
        throw new SQLException(Messages.get("error.statement.noresult"), "24000");
      }
      columns = cursorTds.getColumns();
      columnCount = getColumnCount(columns);
      rowData = new ArrayList(INITIAL_ROW_COUNT);
      //
      // Load result set into buffer
      //
      while (super.next()) {
        rowData.add(copyRow(currentRow));
      }
      rowsInResult = rowData.size();
      initialRowCnt = rowsInResult;
      pos = POS_BEFORE_FIRST;
      if (warning != null) {
        statement.addWarning(warning);
      }
    }
  }