@Override protected final void prepare(ExecuteContext ctx) throws SQLException { // [#1296] These dialects do not implement FOR UPDATE. But the same // effect can be achieved using ResultSet.CONCUR_UPDATABLE if (isForUpdate() && asList(CUBRID, SQLSERVER).contains(ctx.getDialect())) { ctx.statement( ctx.getConnection().prepareStatement(ctx.sql(), TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE)); } // Regular behaviour else { ctx.statement(ctx.getConnection().prepareStatement(ctx.sql())); } // [#1263] Allow for negative fetch sizes to support some non-standard // MySQL feature, where Integer.MIN_VALUE is used if (size != 0) { if (log.isDebugEnabled()) log.debug("Setting fetch size", size); ctx.statement().setFetchSize(size); } // [#1854] Set the max number of rows for this result query if (maxRows != 0) { ctx.statement().setMaxRows(maxRows); } }
@Override protected final int execute(ExecuteContext ctx, ExecuteListener listener) throws SQLException { Connection connection = ctx.getConnection(); boolean autoCommit = false; // [#706] Postgres requires two separate queries running in the same // transaction to be executed when fetching refcursor types if (ctx.getDialect() == SQLDialect.POSTGRES && isSelectingRefCursor()) { autoCommit = connection.getAutoCommit(); if (autoCommit) { if (log.isDebugEnabled()) log.debug("Unsetting auto-commit", false); connection.setAutoCommit(false); } } try { listener.executeStart(ctx); // JTDS doesn't seem to implement PreparedStatement.execute() // correctly, at least not for sp_help if (ctx.getDialect() == ASE) { ctx.resultSet(ctx.statement().executeQuery()); } // [#1232] Avoid executeQuery() in order to handle queries that may // not return a ResultSet, e.g. SQLite's pragma foreign_key_list(table) else if (ctx.statement().execute()) { ctx.resultSet(ctx.statement().getResultSet()); } listener.executeEnd(ctx); // Fetch a single result set if (!many) { if (ctx.resultSet() != null) { FieldList fields = new FieldList(getFields(ctx.resultSet().getMetaData())); cursor = new CursorImpl<R>(ctx, listener, fields, getRecordType()); if (!lazy) { result = cursor.fetch(); cursor = null; } } else { result = new ResultImpl<R>(ctx, new FieldList()); } } // Fetch several result sets else { results = new ArrayList<Result<Record>>(); boolean anyResults = false; while (ctx.resultSet() != null) { anyResults = true; FieldProvider fields = new MetaDataFieldProvider(ctx, ctx.resultSet().getMetaData()); Cursor<Record> c = new CursorImpl<Record>(ctx, listener, fields, true); results.add(c.fetch()); if (ctx.statement().getMoreResults()) { ctx.resultSet(ctx.statement().getResultSet()); } else { ctx.resultSet(null); } } // Call this only when there was at least one ResultSet. // Otherwise, this call is not supported by ojdbc... if (anyResults) { ctx.statement().getMoreResults(Statement.CLOSE_ALL_RESULTS); } ctx.statement().close(); } } finally { if (autoCommit) { if (log.isDebugEnabled()) log.debug("Resetting auto-commit", autoCommit); connection.setAutoCommit(autoCommit); } } return result != null ? result.size() : 0; }