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 + -
显示快捷键?