⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 preparedstatement.java

📁 用java访问MySQL数据库的JDBC驱动程序。
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * MM JDBC Drivers for MySQL
 *
 * $Id: PreparedStatement.java,v 1.2 1998/08/25 00:53:47 mmatthew 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.
 */

/**
 * A SQL Statement is pre-compiled and stored in a PreparedStatement object.
 * This object can then be used to efficiently execute this statement multiple
 * times.
 *
 * <p><B>Note:</B> The setXXX methods for setting IN parameter values must
 * specify types that are compatible with the defined SQL type of the input
 * parameter.  For instance, if the IN parameter has SQL type Integer, then
 * setInt should be used.
 *
 * <p>If arbitrary parameter type conversions are required, then the setObject 
 * method should be used with a target SQL type.
 *
 * @see java.sql.ResultSet
 * @see java.sql.PreparedStatement
 * @author Mark Matthews <mmatthew@worldserver.com>
 * @version $Id$
 */

package org.gjt.mm.mysql;

import java.io.*;
import java.math.*;
import java.sql.*;
import java.text.*;
import java.util.*;

public class PreparedStatement extends org.gjt.mm.mysql.Statement 
    implements java.sql.PreparedStatement  
{

    private String        _Sql              = null;
    private String[]      _TemplateStrings  = null;
    private String[]      _ParameterStrings = null;
    private InputStream[] _ParameterStreams = null;
    private boolean[]     _IsStream         = null;
    private Connection    _Conn             = null;

    private boolean       _do_concat        = false;
    private boolean       _has_limit_clause = false;
    
    /**
     * Constructor for the PreparedStatement class.
     * Split the SQL statement into segments - separated by the arguments.
     * When we rebuild the thing with the arguments, we can substitute the
     * args and join the whole thing together.
     *
     * @param conn the instanatiating connection
     * @param sql the SQL statement with ? for IN markers
     * @exception java.sql.SQLException if something bad occurs
     */

    public PreparedStatement(Connection Conn, String Sql, String Catalog) throws java.sql.SQLException
    {
	super(Conn, Catalog);

	if (Sql.indexOf("||") != -1) {
	    _do_concat = true;
	}
	
	_has_limit_clause = (Sql.toUpperCase().indexOf("LIMIT") != -1);

	Vector V = new Vector();
	boolean inQuotes = false;
	int lastParmEnd = 0, i;

	_Sql = Sql;
	_Conn = Conn;

	for (i = 0; i < _Sql.length(); ++i) {
	    int c = _Sql.charAt(i);
		    
	    if (c == '\'')
		inQuotes = !inQuotes;
	    if (c == '?' && !inQuotes)
		{
		    V.addElement(_Sql.substring (lastParmEnd, i));
		    lastParmEnd = i + 1;
		}
	}
	V.addElement(_Sql.substring (lastParmEnd, _Sql.length()));

	_TemplateStrings = new String[V.size()];
	_ParameterStrings = new String[V.size() - 1];
	_ParameterStreams = new InputStream[V.size() - 1];
	_IsStream         = new boolean[V.size() - 1];
	clearParameters();

	for (i = 0 ; i < _TemplateStrings.length; ++i) {
	    _TemplateStrings[i] = (String)V.elementAt(i);
	}

	for (int j = 0; j < _ParameterStrings.length; j++) {
	    _IsStream[j] = false;
	}
    }

    /**
     * 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 java.sql.SQLException if a database access error occurs
     */

    public java.sql.ResultSet executeQuery() throws java.sql.SQLException
    {
	boolean do_escape_processing = _escapeProcessing;
	_escapeProcessing = false; // Do escape processing part-by-part
   
	Buffer Packet = new Buffer(MysqlIO.getMaxBuf());
	Packet.writeByte((byte)MysqlDefs.QUERY);
	      
	String Encoding = null;

	if (_Conn.useUnicode()) {
	    Encoding = _Conn.getEncoding();
	}

	try {
	    for (int i = 0 ; i < _ParameterStrings.length ; ++i) {

		if (_ParameterStrings[i] == null && 
		    (_IsStream[i] && _ParameterStreams[i] == null)) {
		    throw new java.sql.SQLException("No value specified for parameter " + (i + 1), "07001");
		}

		if (Encoding != null) {
		    Packet.writeStringNoNull(_TemplateStrings[i], Encoding);
		}
		else {
		    Packet.writeStringNoNull(_TemplateStrings[i]);
		}
	    
		if (_IsStream[i]) {
		    Packet.writeBytesNoNull(streamToBytes(_ParameterStreams[i]));
		}
		else {
		    if (do_escape_processing) {
			_ParameterStrings[i] = _Escaper.escapeSQL(_ParameterStrings[i]);
		    }
			
		    if (Encoding != null) {
			Packet.writeStringNoNull(_ParameterStrings[i], Encoding);
		    }
		    else {
			Packet.writeStringNoNull(_ParameterStrings[i]);
		    }
		}
	    }

	    if (Encoding != null) {
		Packet.writeStringNoNull(_TemplateStrings[_ParameterStrings.length], Encoding);
	    }
	    else {
		Packet.writeStringNoNull(_TemplateStrings[_ParameterStrings.length]);
	    }
	}
	catch (java.io.UnsupportedEncodingException UE) {
	    throw new SQLException("Unsupported character encoding '" + Encoding + "'");
	}
		
	if (_Results != null) {
	    _Results.close();
	}

	// 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 (_Conn.getMutex()) {
	    String OldCatalog = null;

	    if (!_Conn.getCatalog().equals(_Catalog)) {
		OldCatalog = _Conn.getCatalog();
		_Conn.setCatalog(_Catalog);
	    }

	    if (_Conn.useMaxRows()) {

		// 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).

		if (_has_limit_clause) { 
		    _Results = _Conn.execSQL(null, _max_rows, Packet);
		}
		else {
		    if (_max_rows <= 0) {
			_Conn.execSQL("SET OPTION SQL_SELECT_LIMIT=" 
				      + MysqlDefs.MAX_ROWS, -1);
		    }
		    else {
			_Conn.execSQL("SET OPTION SQL_SELECT_LIMIT=" + _max_rows,-1);
		    }
			        		            
		    _Results = _Conn.execSQL(null, -1, Packet);

		    if (OldCatalog != null) {
			_Conn.setCatalog(OldCatalog);
		    }
		}
	    }
	    else {
		_Results = _Conn.execSQL(null, -1, Packet);	    
	    }

	    if (OldCatalog != null) {
		_Conn.setCatalog(OldCatalog);
	    }
	}

	_last_insert_id = _Results.getUpdateID();
	_NextResults = _Results;
	_Results.setConnection(_Conn);
	
	_escapeProcessing = do_escape_processing;
	
	return _Results;
    }

    /**
     * Execute a SQL INSERT, UPDATE or DELETE statement.  In addition,
     * SQL statements that return nothing such as SQL DDL statements can
     * be executed.
     *
     * @return either the row count for INSERT, UPDATE or DELETE; or
     *      0 for SQL statements that return nothing.
     * @exception java.sql.SQLException if a database access error occurs
     */

    public int executeUpdate() throws java.sql.SQLException
    {
	boolean do_escape_processing = _escapeProcessing;
	_escapeProcessing = false;
		            
	Buffer Packet = new Buffer(MysqlIO.getMaxBuf());
	Packet.writeByte((byte)MysqlDefs.QUERY);
	
	String Encoding = null;

	if (_Conn.useUnicode()) {
	    Encoding = _Conn.getEncoding();
	}

	try {
	    for (int i = 0 ; i < _ParameterStrings.length ; ++i) {
		if (_ParameterStrings[i] == null && 
		    (_IsStream[i] && _ParameterStreams[i] == null)) {
		    throw new java.sql.SQLException("No value specified for parameter " + (i + 1), "07001");
		}

		if (Encoding != null) {
		    Packet.writeStringNoNull(_TemplateStrings[i], Encoding);
		}
		else {
		    Packet.writeStringNoNull(_TemplateStrings[i]);
		}
		    
		if (_IsStream[i]) {
		    Packet.writeBytesNoNull(streamToBytes(_ParameterStreams[i]));
		}
		else {
		    if (do_escape_processing) {
			_ParameterStrings[i] = _Escaper.escapeSQL(_ParameterStrings[i]);
		    }
			
		    if (Encoding != null) {
			Packet.writeStringNoNull(_ParameterStrings[i], Encoding);
		    }
		    else {
			Packet.writeStringNoNull(_ParameterStrings[i]);
		    }
		}
	    }
		
	    if (Encoding != null) {
		Packet.writeStringNoNull(_TemplateStrings[_ParameterStrings.length], Encoding);
	    }
	    else {
		Packet.writeStringNoNull(_TemplateStrings[_ParameterStrings.length]);
	    }
	}
	catch (java.io.UnsupportedEncodingException UE) {
	    throw new SQLException("Unsupported character encoding '" + Encoding + "'");
	}
		
	// 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);
	    }

	    RS = _Conn.execSQL(null, -1, Packet);

	    if (OldCatalog != null) {
		_Conn.setCatalog(OldCatalog);
	    }
	}
	
	if (RS.reallyResult()) {
	    throw new java.sql.SQLException("Results returned for UPDATE ONLY.", "01S03");
	}
	else {
	    _update_count = RS.getUpdateCount();
		    
	    int truncated_update_count = 0;

	    if (_update_count > Integer.MAX_VALUE) {
		truncated_update_count = Integer.MAX_VALUE;
	    }
	    else {
		truncated_update_count = (int)_update_count;
	    }

	    _last_insert_id = RS.getUpdateID();
		    
	    _escapeProcessing = do_escape_processing;
			
	    return truncated_update_count;
	}
    }       

    /**
     * Set a parameter to SQL NULL
     *
     * <p><B>Note:</B> You must specify the parameters SQL type (although
     * PostgreSQL ignores it)
     *
     * @param parameterIndex the first parameter is 1, etc...
     * @param sqlType the SQL type code defined in java.sql.Types
     * @exception java.sql.SQLException if a database access error occurs
     */

    public void setNull(int parameterIndex, int sqlType) throws java.sql.SQLException
    {
	set(parameterIndex, "null");
    }

    /**
     * Set a parameter to a Java boolean value.  The driver converts this
     * to a SQL BIT value when it sends it to the database.
     *
     * @param parameterIndex the first parameter is 1...
     * @param x the parameter value
     * @exception java.sql.SQLException if a database access error occurs
     */
    public void setBoolean(int parameterIndex, boolean x) throws java.sql.SQLException
    {
	set(parameterIndex, x ? "'t'" : "'f'");
    }

    /**
     * Set a parameter to a Java byte value.  The driver converts this to
     * a SQL TINYINT value when it sends it to the database.
     *
     * @param parameterIndex the first parameter is 1...
     * @param x the parameter value
     * @exception java.sql.SQLException if a database access error occurs
     */
    public void setByte(int parameterIndex, byte x) throws java.sql.SQLException
    {
	set(parameterIndex, (new Integer(x)).toString());
    }

    /**
     * Set a parameter to a Java short value.  The driver converts this
     * to a SQL SMALLINT value when it sends it to the database.
     *
     * @param parameterIndex the first parameter is 1...
     * @param x the parameter value
     * @exception java.sql.SQLException if a database access error occurs
     */
    public void setShort(int parameterIndex, short x) throws java.sql.SQLException
    {
	set(parameterIndex, (new Integer(x)).toString());
    }

    /**
     * Set a parameter to a Java int value.  The driver converts this to
     * a SQL INTEGER value when it sends it to the database.
     *
     * @param parameterIndex the first parameter is 1...
     * @param x the parameter value
     * @exception java.sql.SQLException if a database access error occurs
     */
    public void setInt(int parameterIndex, int x) throws java.sql.SQLException
    {
	set(parameterIndex, (new Integer(x)).toString());
    }

    /**
     * Set a parameter to a Java long value.  The driver converts this to
     * a SQL BIGINT value when it sends it to the database.
     *
     * @param parameterIndex the first parameter is 1...
     * @param x the parameter value
     * @exception java.sql.SQLException if a database access error occurs
     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -