📄 statement.java
字号:
/*
* MM JDBC Drivers for MySQL
*
* $Id: Statement.java,v 1.3 2002/04/21 03:03:47 mark_matthews Exp $
*
* Copyright (C) 1998 Mark Matthews <mmatthew@worldserver.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* See the COPYING file located in the top-level-directory of
* the archive of this library for complete text of license.
*
* Some portions:
*
* Copyright (c) 1996 Bradley McLean / Jeffrey Medeiros
* Modifications Copyright (c) 1996/1997 Martin Rode
* Copyright (c) 1997 Peter T Mount
*/
/**
* A Statement object is used for executing a static SQL statement and
* obtaining the results produced by it.
*
* <p>Only one ResultSet per Statement can be open at any point in time.
* Therefore, if the reading of one ResultSet is interleaved with the
* reading of another, each must have been generated by different
* Statements. All statement execute methods implicitly close a
* statement's current ResultSet if an open one exists.
*
* @see java.sql.Statement
* @see ResultSet
* @author Mark Matthews <mmatthew@worldserver.com>
* @version $Id: Statement.java,v 1.3 2002/04/21 03:03:47 mark_matthews Exp $
*/
package com.mysql.jdbc;
import java.sql.*;
import java.util.Vector;
public class Statement {
/**
* The connection who created us
*/
protected Connection _conn = null;
protected int _resultSetType = 0;
protected int _resultSetConcurrency = 0;
/**
* Holds batched commands
*/
protected Vector _batchedArgs;
/**
* The current results
*/
ResultSet _results = null;
/**
* The next result set
*/
ResultSet _nextResults = null;
/**
* The warnings chain.
*/
SQLWarning _warnings = null;
/**
* The timeout for a query
*/
int _timeout = 0;
/**
* Should we process escape codes?
*/
boolean _escapeProcessing = true;
/**
* Processes JDBC escape codes
*/
EscapeProcessor _escaper = null;
int _maxFieldSize = MysqlIO.MAXBUF;
int _maxRows = -1;
long _updateCount = -1;
long _lastInsertId = -1;
String _catalog = null;
/**
* Constructor for a Statement. It simply sets the connection
* that created us.
*
* @param c the Connection instantation that creates us
*/
public Statement(Connection c, String catalog) {
if (Driver.trace) {
Object[] Args = { c };
Debug.methodCall(this, "constructor", Args);
}
_conn = c;
_escaper = new EscapeProcessor();
_catalog = catalog;
//
// Adjust, if we know it
//
if (_conn != null) {
_maxFieldSize = _conn.getMaxAllowedPacket();
}
}
/**
* Execute a SQL statement that retruns a single ResultSet
*
* @param Sql typically a static SQL SELECT statement
* @return a ResulSet that contains the data produced by the query
* @exception java.sql.SQLException if a database access error occurs
*/
public java.sql.ResultSet executeQuery(String sql)
throws java.sql.SQLException {
if (Driver.trace) {
Object[] Args = { sql };
Debug.methodCall(this, "executeQuery", Args);
}
if (_escapeProcessing) {
sql = _escaper.escapeSQL(sql);
}
if (_results != null) {
_results.close();
}
// 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).
synchronized (_conn.getMutex()) {
String oldCatalog = null;
if (!_conn.getCatalog().equals(_catalog)) {
oldCatalog = _conn.getCatalog();
_conn.setCatalog(_catalog);
}
if (_conn.useMaxRows()) {
// We need to execute this all together
// So synchronize on the Connection's mutex (because
// even queries going through there synchronize
// on the connection
if (sql.toUpperCase().indexOf("LIMIT") != -1) {
_results = _conn.execSQL(sql, _maxRows);
}
else {
if (_maxRows <= 0) {
_conn.execSQL("SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1);
}
else {
_conn.execSQL("SET OPTION SQL_SELECT_LIMIT=" + _maxRows, -1);
}
_results = _conn.execSQL(sql, -1);
if (oldCatalog != null) {
_conn.setCatalog(oldCatalog);
}
}
}
else {
_results = _conn.execSQL(sql, -1);
}
if (oldCatalog != null) {
_conn.setCatalog(oldCatalog);
}
}
_lastInsertId = _results.getUpdateID();
_nextResults = _results;
_results.setConnection(_conn);
_results.setResultSetType(_resultSetType);
_results.setResultSetConcurrency(_resultSetConcurrency);
_results.setStatement(this);
return (java.sql.ResultSet) _results;
}
/**
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition
* SQL statements that return nothing such as SQL DDL statements
* can be executed
*
* Any IDs generated for AUTO_INCREMENT fields can be retrieved
* by casting this Statement to org.gjt.mm.mysql.Statement and
* calling the getLastInsertID() method.
*
* @param Sql a SQL statement
* @return either a row count, or 0 for SQL commands
* @exception java.sql.SQLException if a database access error occurs
*/
public int executeUpdate(String sql) throws java.sql.SQLException {
if (Driver.trace) {
Object[] Args = { sql };
Debug.methodCall(this, "executeUpdate", Args);
}
if (_escapeProcessing) {
sql = _escaper.escapeSQL(sql);
}
// The checking and changing of catalogs
// must happen in sequence, so synchronize
// on the same mutex that _conn is using
ResultSet rs = null;
synchronized (_conn.getMutex()) {
String oldCatalog = null;
if (!_conn.getCatalog().equals(_catalog)) {
oldCatalog = _conn.getCatalog();
_conn.setCatalog(_catalog);
}
//
// Only apply max_rows to selects
//
if (_conn.useMaxRows()) {
_conn.execSQL("SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1);
}
rs = _conn.execSQL(sql, -1);
rs.setConnection(_conn);
if (oldCatalog != null) {
_conn.setCatalog(oldCatalog);
}
}
if (rs.reallyResult()) {
throw new java.sql.SQLException("Results returned for UPDATE ONLY.", "01S03");
}
else {
_updateCount = rs.getUpdateCount();
int truncated_updateCount = 0;
if (_updateCount > Integer.MAX_VALUE) {
truncated_updateCount = Integer.MAX_VALUE;
}
else {
truncated_updateCount = (int) _updateCount;
}
_lastInsertId = rs.getUpdateID();
return truncated_updateCount;
}
}
/**
* In many cases, it is desirable to immediately release a
* Statement's database and JDBC resources instead of waiting
* for this to happen when it is automatically closed. The
* close method provides this immediate release.
*
* <p><B>Note:</B> A Statement is automatically closed when it is
* garbage collected. When a Statement is closed, its current
* ResultSet, if one exists, is also closed.
*
* @exception java.sql.SQLException if a database access error occurs
*/
public void close() throws java.sql.SQLException {
if (Driver.trace) {
Object[] Args = new Object[0];
Debug.methodCall(this, "close", Args);
}
if (_results != null) {
try
{
_results.close();
}
catch (Exception ex) {
}
}
_results = null;
_conn = null;
_warnings = null;
_escaper = null;
}
/**
* The maxFieldSize limit (in bytes) is the maximum amount of
* data returned for any column value; it only applies to
* BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR and LONGVARCHAR
* columns. If the limit is exceeded, the excess data is silently
* discarded.
*
* @return the current max column size limit; zero means unlimited
* @exception java.sql.SQLException if a database access error occurs
*/
public int getMaxFieldSize() throws java.sql.SQLException {
if (Driver.trace) {
Object[] Args = new Object[0];
Debug.methodCall(this, "getMaxFieldSize", Args);
}
return _maxFieldSize; // Init. set to MAXBUFFER in MysqlIO
}
/**
* Sets the maxFieldSize
*
* @param max the new max column size limit; zero means unlimited
* @exception java.sql.SQLException if size exceeds buffer size
*/
public void setMaxFieldSize(int max) throws java.sql.SQLException {
if (Driver.trace) {
Object[] Args = { new Integer(max)};
Debug.methodCall(this, "setMaxFieldSize", Args);
}
int max_buf = (_conn != null) ? _conn.getMaxAllowedPacket() : MysqlIO.MAXBUF;
if (max > max_buf) {
throw new java.sql.SQLException(
"Can not set max field size > max allowed packet: " + max_buf,
"S1009");
}
else {
_maxFieldSize = max;
}
}
/**
* The maxRows limit is set to limit the number of rows that
* any ResultSet can contain. If the limit is exceeded, the
* excess rows are silently dropped.
*
* @return the current maximum row limit; zero means unlimited
* @exception java.sql.SQLException if a database access error occurs
*/
public int getMaxRows() throws java.sql.SQLException {
if (Driver.trace) {
Object[] Args = new Object[0];
Debug.methodCall(this, "getMaxRows", Args);
}
if (_maxRows <= 0) {
return 0;
}
else {
return _maxRows;
}
}
/**
* Set the maximum number of rows
*
* @param max the new max rows limit; zero means unlimited
* @exception java.sql.SQLException if a database access error occurs
* @see getMaxRows
*/
public void setMaxRows(int max) throws java.sql.SQLException {
if (Driver.trace) {
Object[] Args = { new Integer(max)};
Debug.methodCall(this, "setMaxRows", Args);
}
if (max > MysqlDefs.MAX_ROWS) {
throw new java.sql.SQLException(
"setMaxRows() out of range. " + max + " > " + MysqlDefs.MAX_ROWS + ".",
"S1009");
}
if (max == 0) {
max = -1;
}
_maxRows = max;
// Most people don't use setMaxRows()
// so don't penalize them
// with the extra query it takes
// to do it efficiently unless we need
// to.
_conn.maxRowsChanged();
}
/**
* If escape scanning is on (the default), the driver will do escape
* substitution before sending the SQL to the database.
*
* @param enable true to enable; false to disable
* @exception java.sql.SQLException if a database access error occurs
*/
public void setEscapeProcessing(boolean enable) throws java.sql.SQLException {
if (Driver.trace) {
Object[] Args = { new Boolean(enable)};
Debug.methodCall(this, "setEscapeProcessing", Args);
}
_escapeProcessing = enable;
}
/**
* The queryTimeout limit is the number of seconds the driver
* will wait for a Statement to execute. If the limit is
* exceeded, a java.sql.SQLException is thrown.
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -