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

📄 preparedstatement.java

📁 SearchPathServer
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * MM JDBC Drivers for MySQL
 *
 * $Id: PreparedStatement.java,v 1.6 2002/05/07 21:25:58 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.
 */

/**
 * 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: PreparedStatement.java,v 1.6 2002/05/07 21:25:58 mark_matthews Exp $
 */

package com.mysql.jdbc;

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

public class PreparedStatement extends com.mysql.jdbc.Statement
{
	protected static SimpleDateFormat _TSDF =
		new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	private String _Sql = null;
	private byte[][] _TemplateStrings = null;
	protected String[] _ParameterStrings = null;
	protected InputStream[] _ParameterStreams = null;
	protected boolean[] _IsStream = null;
	protected boolean[] _IsNull = null;

	private boolean _has_limit_clause = false;

	private byte[] _bi = new byte[4096];

	private Buffer _SendPacket = null;

	private boolean _useTrueBoolean = false;

	private static java.util.Hashtable templateCache = new java.util.Hashtable();

	private char _firstChar;

	class EndPoint
	{
		int begin;
		int end;

		EndPoint(int b, int e)
		{
			begin = b;
			end = e;
		}
	}

	/**
	 * 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);

		_useTrueBoolean = _conn.getIO().versionMeetsMinimum(3, 21, 23);

		_firstChar = Character.toUpperCase(Sql.charAt(0));

		_has_limit_clause = (Sql.toUpperCase().indexOf("LIMIT") != -1);

		char[] statementAsChars = Sql.toCharArray();

		int statementLength = statementAsChars.length;

		int placeHolderCount = 0;

		for (int i = 0; i < statementLength; i++)
		{
			if (statementAsChars[i] == '?')
			{
				placeHolderCount++;
			}
		}

		// _TemplateStrings = (byte[][])templateCache.get(Sql);

		//if (_TemplateStrings == null) {
		Vector V = new Vector(placeHolderCount + 1);
		boolean inQuotes = false;
		int lastParmEnd = 0, i;

		_Sql = Sql;
		_conn = Conn;

		int pre1 = 0;
		int pre2 = 0;

		for (i = 0; i < statementLength; ++i)
		{
			int c = statementAsChars[i];

			if (c == '\'' && pre1 == '\\' && pre2 == '\\')
			{
				inQuotes = !inQuotes;
			}
			else if (c == '\'' && pre1 != '\\')
			{
				inQuotes = !inQuotes;
			}

			if (c == '?' && !inQuotes)
			{

				//V.addElement(_Sql.substring (lastParmEnd, i));
				V.addElement(new EndPoint(lastParmEnd, i));

				lastParmEnd = i + 1;
			}
			pre2 = pre1;
			pre1 = c;
		}
		//V.addElement(_Sql.substring (lastParmEnd, _Sql.length()));

		V.addElement(new EndPoint(lastParmEnd, statementLength));

		_TemplateStrings = new byte[V.size()][];

		String Encoding = null;

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

		for (i = 0; i < _TemplateStrings.length; i++)
		{
			if (Encoding == null)
			{
				//        String str = (String)V.elementAt(i);

				//int len = str.length();

				//byte[] buf = new byte[len];

				//for (int j = 0; j < len; j++) {
				//    buf[j] = (byte)str.charAt(j);
				//}

				//_TemplateStrings[i] = buf;

				EndPoint ep = (EndPoint) V.elementAt(i);

				int end = ep.end;
				int begin = ep.begin;

				int len = end - begin;

				byte[] buf = new byte[len];

				for (int j = 0; j < len; j++)
				{

					buf[j] = (byte) statementAsChars[begin + j];
				}

				_TemplateStrings[i] = buf;
			}
			else
			{
				try
				{
					EndPoint ep = (EndPoint) V.elementAt(i);

					int end = ep.end;
					int begin = ep.begin;

					int len = end - begin;

					String temp = new String(statementAsChars, begin, len);

					_TemplateStrings[i] = temp.getBytes(Encoding);
				}
				catch (java.io.UnsupportedEncodingException ue)
				{
					throw new SQLException(ue.toString());
				}
			}
		}

		//    templateCache.put(Sql, _TemplateStrings);
		// }

		_ParameterStrings = new String[_TemplateStrings.length - 1];
		_ParameterStreams = new InputStream[_TemplateStrings.length - 1];
		_IsStream = new boolean[_TemplateStrings.length - 1];
		_IsNull = new boolean[_TemplateStrings.length - 1];

		clearParameters();

		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
	{

		if (_SendPacket == null)
		{
			_SendPacket =
				new Buffer(_conn.getNetBufferLength(), _conn.getMaxAllowedPacket());
		}
		else
		{
			_SendPacket.clear();
		}

		_SendPacket.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 && _ParameterStreams[i] == null)
				{
					throw new java.sql.SQLException(
						"No value specified for parameter " + (i + 1),
						"07001");
				}

				//if (Encoding != null) {
				_SendPacket.writeBytesNoNull(_TemplateStrings[i]);
				//}
				//else {
				//    _SendPacket.writeStringNoNull(_TemplateStrings[i]);
				//}

				if (_IsStream[i])
				{
					_SendPacket.writeBytesNoNull(streamToBytes(_ParameterStreams[i]));
				}
				else
				{
					if (Encoding != null)
					{
						_SendPacket.writeStringNoNull(_ParameterStrings[i], Encoding);
					}
					else
					{
						_SendPacket.writeStringNoNull(_ParameterStrings[i]);
					}
				}
			}

			_SendPacket.writeBytesNoNull(_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, _maxRows, _SendPacket);
				}
				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(null, -1, _SendPacket);

					if (OldCatalog != null)
					{
						_conn.setCatalog(OldCatalog);
					}
				}
			}
			else
			{
				_results = _conn.execSQL(null, -1, _SendPacket);
			}

			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.
	 *
	 * @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
	{
		return executeUpdate(_ParameterStrings, _ParameterStreams, _IsStream, _IsNull);
	}

	/**
	 * Added to allow batch-updates
	 */

	protected int executeUpdate(
		String[] ParameterStrings,
		InputStream[] ParameterStreams,
		boolean[] IsStream,
		boolean[] IsNull)
		throws java.sql.SQLException
	{

		if (_SendPacket == null)
		{
			_SendPacket =
				new Buffer(_conn.getNetBufferLength(), _conn.getMaxAllowedPacket());
		}
		else
		{
			_SendPacket.clear();
		}

		_SendPacket.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 && ParameterStreams[i] == null)
				{
					throw new java.sql.SQLException(
						"No value specified for parameter " + (i + 1),
						"07001");
				}

				//if (Encoding != null) {
				_SendPacket.writeBytesNoNull(_TemplateStrings[i]);
				//}
				//else {
				//   _SendPacket.writeStringNoNull(_TemplateStrings[i]);
				//}

				if (IsStream[i])
				{
					_SendPacket.writeBytesNoNull(streamToBytes(ParameterStreams[i]));
				}
				else
				{
					if (Encoding != null)
					{
						_SendPacket.writeStringNoNull(ParameterStrings[i], Encoding);
					}
					else
					{
						_SendPacket.writeStringNoNull(ParameterStrings[i]);
					}
				}
			}

			//if (Encoding != null) {
			_SendPacket.writeBytesNoNull(_TemplateStrings[ParameterStrings.length]);
			// }
			// else {
			//	_SendPacket.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);
			}

			// 
			// Only apply max_rows to selects
			//

			if (_conn.useMaxRows())
			{
				_conn.execSQL("SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1);
			}

			RS = _conn.execSQL(null, -1, _SendPacket);

			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;
		}
	}

	/**
	 * Set a parameter to SQL NULL
	 *
	 * <p><B>Note:</B> You must specify the parameters SQL type (although
	 * MySQL 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");
		_IsNull[parameterIndex - 1] = true;
	}

	/**
	 * 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
	{
		if (_useTrueBoolean)
		{
			set(parameterIndex, x ? "'1'" : "'0'");
		}
		else
		{
			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, String.valueOf(x));

⌨️ 快捷键说明

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