preparedstatement.java
来自「mysql的jdbc驱动」· Java 代码 · 共 2,423 行 · 第 1/5 页
JAVA
2,423 行
} /** * JDBC 2.0 Add a set of parameters to the batch. * * @exception SQLException * if a database-access error occurs. * * @see Statement#addBatch */ public void addBatch() throws SQLException { if (this.batchedArgs == null) { this.batchedArgs = new ArrayList(); } this.batchedArgs.add(new BatchParams(this.parameterValues, this.parameterStreams, this.isStream, this.streamLengths, this.isNull)); } protected String asSql() throws SQLException { return asSql(false); } protected String asSql(boolean quoteStreamsAndUnknowns) throws SQLException { StringBuffer buf = new StringBuffer(); try { for (int i = 0; i < this.parameterCount; ++i) { if (this.charEncoding != null) { buf.append(new String(this.staticSqlStrings[i], this.charEncoding)); } else { buf.append(new String(this.staticSqlStrings[i])); } if ((this.parameterValues[i] == null) && !this.isStream[i]) { if (quoteStreamsAndUnknowns) { buf.append("'"); } buf.append("** NOT SPECIFIED **"); //$NON-NLS-1$ if (quoteStreamsAndUnknowns) { buf.append("'"); } } else if (this.isStream[i]) { if (quoteStreamsAndUnknowns) { buf.append("'"); } buf.append("** STREAM DATA **"); //$NON-NLS-1$ if (quoteStreamsAndUnknowns) { buf.append("'"); } } else { if (this.charConverter != null) { buf.append(this.charConverter .toString(this.parameterValues[i])); } else { if (this.charEncoding != null) { buf.append(new String(this.parameterValues[i], this.charEncoding)); } else { buf.append(StringUtils .toAsciiString(this.parameterValues[i])); } } } } if (this.charEncoding != null) { buf.append(new String( this.staticSqlStrings[this.parameterCount], this.charEncoding)); } else { buf .append(StringUtils .toAsciiString(this.staticSqlStrings[this.parameterCount])); } } catch (UnsupportedEncodingException uue) { throw new RuntimeException(Messages .getString("PreparedStatement.32") //$NON-NLS-1$ + this.charEncoding + Messages.getString("PreparedStatement.33")); //$NON-NLS-1$ } return buf.toString(); } /** * In general, parameter values remain in force for repeated used of a * Statement. Setting a parameter value automatically clears its previous * value. However, in some cases, it is useful to immediately release the * resources used by the current parameter values; this can be done by * calling clearParameters * * @exception SQLException * if a database access error occurs */ public void clearParameters() throws SQLException { for (int i = 0; i < this.parameterValues.length; i++) { this.parameterValues[i] = null; this.parameterStreams[i] = null; this.isStream[i] = false; this.isNull[i] = false; } } /** * Closes this prepared statement and releases all resources. * * @throws SQLException * if database error occurs. */ public synchronized void close() throws SQLException { realClose(true); } private final void escapeblockFast(byte[] buf, Buffer packet, int size) throws SQLException { int lastwritten = 0; for (int i = 0; i < size; i++) { byte b = buf[i]; if (b == '\0') { // write stuff not yet written if (i > lastwritten) { packet.writeBytesNoNull(buf, lastwritten, i - lastwritten); } // write escape packet.writeByte((byte) '\\'); packet.writeByte((byte) '0'); lastwritten = i + 1; } else { if ((b == '\\') || (b == '\'') || (!this.usingAnsiMode && b == '"')) { // write stuff not yet written if (i > lastwritten) { packet.writeBytesNoNull(buf, lastwritten, i - lastwritten); } // write escape packet.writeByte((byte) '\\'); lastwritten = i; // not i+1 as b wasn't written. } } } // write out remaining stuff from buffer if (lastwritten < size) { packet.writeBytesNoNull(buf, lastwritten, size - lastwritten); } } private final void escapeblockFast(byte[] buf, ByteArrayOutputStream bytesOut, int size) { int lastwritten = 0; for (int i = 0; i < size; i++) { byte b = buf[i]; if (b == '\0') { // write stuff not yet written if (i > lastwritten) { bytesOut.write(buf, lastwritten, i - lastwritten); } // write escape bytesOut.write('\\'); bytesOut.write('0'); lastwritten = i + 1; } else { if ((b == '\\') || (b == '\'') || (!this.usingAnsiMode && b == '"')) { // write stuff not yet written if (i > lastwritten) { bytesOut.write(buf, lastwritten, i - lastwritten); } // write escape bytesOut.write('\\'); lastwritten = i; // not i+1 as b wasn't written. } } } // write out remaining stuff from buffer if (lastwritten < size) { bytesOut.write(buf, lastwritten, size - lastwritten); } } /** * Some prepared statements return multiple results; the execute method * handles these complex statements as well as the simpler form of * statements handled by executeQuery and executeUpdate * * @return true if the next result is a ResultSet; false if it is an update * count or there are no more results * * @exception SQLException * if a database access error occurs */ public boolean execute() throws SQLException { if (this.connection.isReadOnly() && (this.firstCharOfStmt != 'S')) { throw new SQLException(Messages.getString("PreparedStatement.20") //$NON-NLS-1$ + Messages.getString("PreparedStatement.21"), //$NON-NLS-1$ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } checkClosed(); ResultSet rs = null; synchronized (this.connection.getMutex()) { clearWarnings(); this.batchedGeneratedKeys = null; Buffer sendPacket = fillSendPacket(); String oldCatalog = null; if (!this.connection.getCatalog().equals(this.currentCatalog)) { oldCatalog = this.connection.getCatalog(); this.connection.setCatalog(this.currentCatalog); } boolean oldInfoMsgState = false; if (this.retrieveGeneratedKeys) { oldInfoMsgState = this.connection.isReadInfoMsgEnabled(); this.connection.setReadInfoMsgEnabled(true); } // If there isn't a limit clause in the SQL // then limit the number of rows to return in // an efficient manner. Only do this if // setMaxRows() hasn't been used on any Statements // generated from the current Connection (saves // a query, and network traffic). // // Only apply max_rows to selects // if (this.connection.useMaxRows()) { int rowLimit = -1; if (this.firstCharOfStmt == 'S') { if (this.hasLimitClause) { rowLimit = this.maxRows; } else { if (this.maxRows <= 0) { this.connection.execSQL(this, "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, //$NON-NLS-1$ null, java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, false, this.currentCatalog, true); } else { this.connection .execSQL( this, "SET OPTION SQL_SELECT_LIMIT=" + this.maxRows, -1, //$NON-NLS-1$ null, java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, false, this.currentCatalog, true); } } } else { this.connection.execSQL(this, "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, //$NON-NLS-1$ java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, false, this.currentCatalog, true); } // Finally, execute the query rs = executeInternal(rowLimit, sendPacket, createStreamingResultSet(), (this.firstCharOfStmt == 'S'), true); } else { rs = executeInternal(-1, sendPacket, createStreamingResultSet(), (this.firstCharOfStmt == 'S'), true); } if (this.retrieveGeneratedKeys) { this.connection.setReadInfoMsgEnabled(oldInfoMsgState); rs.setFirstCharOfQuery('R'); } if (oldCatalog != null) { this.connection.setCatalog(oldCatalog); } this.lastInsertId = rs.getUpdateID(); if (rs != null) { this.results = rs; } } return ((rs != null) && rs.reallyResult()); } /** * JDBC 2.0 Submit a batch of commands to the database for execution. This * method is optional. * * @return an array of update counts containing one element for each command * in the batch. The array is ordered according to the order in * which commands were inserted into the batch * * @exception SQLException * if a database-access error occurs, or the driver does not * support batch statements * @throws java.sql.BatchUpdateException * DOCUMENT ME! */ public int[] executeBatch() throws SQLException { if (this.connection.isReadOnly()) { throw new SQLException(Messages.getString("PreparedStatement.25") //$NON-NLS-1$ + Messages.getString("PreparedStatement.26"), //$NON-NLS-1$ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } try { clearWarnings(); int[] updateCounts = null; if (this.batchedArgs != null) { int nbrCommands = this.batchedArgs.size(); updateCounts = new int[nbrCommands]; for (int i = 0; i < nbrCommands; i++) { updateCounts[i] = -3; } SQLException sqlEx = null; int commandIndex = 0; if (this.retrieveGeneratedKeys) { this.batchedGeneratedKeys = new ArrayList(nbrCommands); } for (commandIndex = 0; commandIndex < nbrCommands; commandIndex++) { Object arg = this.batchedArgs.get(commandIndex); if (arg instanceof String) { updateCounts[commandIndex] = executeUpdate((String) arg); } else { BatchParams paramArg = (BatchParams) arg; try { updateCounts[commandIndex] = executeUpdate( paramArg.parameterStrings, paramArg.parameterStreams, paramArg.isStream, paramArg.streamLengths, paramArg.isNull); if (this.retrieveGeneratedKeys) { java.sql.ResultSet rs = null; try { // we don't want to use our version, // because we've altered the behavior of // ours to support batch updates // (catch-22) rs = super.getGeneratedKeys(); while (rs.next()) { this.batchedGeneratedKeys .add(new byte[][] { rs .getBytes(1) }); } } finally { if (rs != null) { rs.close(); } } } } catch (SQLException ex) { updateCounts[commandIndex] = EXECUTE_FAILED; if (this.connection.getContinueBatchOnError()) { sqlEx = ex; } else { int[] newUpdateCounts = new int[commandIndex]; System.arraycopy(updateCounts, 0, newUpdateCounts, 0, commandIndex); throw new java.sql.BatchUpdateException(ex .getMessage(), ex.getSQLState(), ex .getErrorCode(), newUpdateCounts); } } } } if (sqlEx != null) { throw new java.sql.BatchUpdateException(sqlEx.getMessage(), sqlEx.getSQLState(), sqlEx.getErrorCode(), updateCounts); } } return (updateCounts != null) ? updateCounts : new int[0]; } finally { clearBatch(); } } /** * Actually execute the prepared statement. This is here so server-side * PreparedStatements can re-use most of the code from this class. * * @param maxRowsToRetrieve * the max number of rows to return * @param sendPacket * the packet to send * @param createStreamingResultSet * should a 'streaming' result set be created? * @param queryIsSelectOnly * is this query doing a SELECT? * @param unpackFields * DOCUMENT ME! * * @return the results as a ResultSet * * @throws SQLException * if an error occurs. */ protected ResultSet executeInternal(int maxRowsToRetrieve, Buffer sendPacket, boolean createStreamingResultSet, boolean queryIsSelectOnly, boolean unpackFields) throws SQLException { this.numberOfExecutions++; ResultSet rs; rs = this.connection.execSQL(this, null, maxRowsToRetrieve, sendPacket, this.resultSetType, this.resultSetConcurrency, createStreamingResultSet, false, this.currentCatalog, unpackFields); return rs; } /** * A Prepared SQL query is executed and its ResultSet is returned * * @return a ResultSet that contains the data produced by the query - never * null * * @exception SQLException * if a database access error occurs */ public synchronized java.sql.ResultSet executeQuery() throws SQLException { checkClosed(); checkForDml(this.originalSql, this.firstCharOfStmt); CachedResultSetMetaData cachedMetadata = null; // We need to execute this all together // So synchronize on the Connection's mutex (because // even queries going through there synchronize // on the same mutex. synchronized (this.connection.getMutex()) { clearWarnings(); this.batchedGeneratedKeys = null; Buffer sendPacket = fillSendPacket(); if (this.results != null) { if (!this.connection.getHoldResultsOpenOverStatementClose()) { this.results.realClose(false);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?