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

📄 jtdspreparedstatement.java

📁 第三方的SQL Server and Sybase的jdbc dirver,速度更快
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// jTDS JDBC Driver for Microsoft SQL Server and Sybase// Copyright (C) 2004 The jTDS Project//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 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// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser 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//package net.sourceforge.jtds.jdbc;import java.io.InputStream;import java.io.Reader;import java.math.BigDecimal;import java.net.URL;import java.sql.Array;import java.sql.Blob;import java.sql.Clob;import java.sql.Date;import java.sql.ParameterMetaData;import java.sql.PreparedStatement;import java.sql.Ref;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.sql.Time;import java.sql.Timestamp;import java.util.Calendar;import java.util.Collection;import java.util.ArrayList;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import java.lang.reflect.Constructor;import java.text.NumberFormat;/** * jTDS implementation of the java.sql.PreparedStatement interface. * <p> * Implementation notes: * <ol> * <li>Generally a simple subclass of Statement mainly adding support for the *     setting of parameters. * <li>The stream logic is taken over from the work Brian did to add Blob support *     to the original jTDS. * <li>Use of Statement specific method calls eg executeQuery(sql) is blocked by *     this version of the driver. This is unlike the original jTDS but inline *     with all the other JDBC drivers that I have been able to test. * </ol> * * @author Mike Hutchinson * @author Brian Heineman * @version $Id: JtdsPreparedStatement.java,v 1.51 2005/06/16 09:32:27 alin_sinpalean Exp $ */public class JtdsPreparedStatement extends JtdsStatement implements PreparedStatement {    /** The SQL statement being prepared. */    protected final String sql;    /** The first SQL keyword in the SQL string.*/    protected String sqlWord;    /** The procedure name for CallableStatements. */    protected String procName;    /** The parameter list for the call. */    protected ParamInfo[] parameters;    /** True to return generated keys. */    private boolean returnKeys;    /** The cached parameter meta data. */    protected ParamInfo[] paramMetaData;    /** Used to format numeric values when scale is specified. */    private static NumberFormat f = NumberFormat.getInstance();    /** Collection of handles used by this statement */    Collection handles;    /**     * Construct a new preparedStatement object.     *     * @param connection The parent connection.     * @param sql   The SQL statement to prepare.     * @param resultSetType The result set type eg SCROLLABLE etc.     * @param concurrency The result set concurrency eg READONLY.     * @param returnKeys True if generated keys should be returned.     * @throws SQLException     */    JtdsPreparedStatement(ConnectionJDBC2 connection,                          String sql,                          int resultSetType,                          int concurrency,                          boolean returnKeys)        throws SQLException {        super(connection, resultSetType, concurrency);        // Parse the SQL looking for escapes and parameters        if (this instanceof JtdsCallableStatement) {            sql = normalizeCall(sql);        }        ArrayList params = new ArrayList();        String[] parsedSql = SQLParser.parse(sql, params, connection, false);        if (parsedSql[0].length() == 0) {            throw new SQLException(Messages.get("error.prepare.nosql"), "07000");        }        if (parsedSql[1].length() > 1) {            if (this instanceof JtdsCallableStatement) {                // Procedure call                this.procName = parsedSql[1];            }        }        sqlWord = parsedSql[2];        if (returnKeys && sqlWord.equals("insert")) {            if (connection.getServerType() == Driver.SQLSERVER                    && connection.getDatabaseMajorVersion() >= 8) {                this.sql = parsedSql[0] + " SELECT SCOPE_IDENTITY() AS ID";            } else {                this.sql = parsedSql[0] + " SELECT @@IDENTITY AS ID";            }            this.returnKeys = true;        } else {            this.sql = parsedSql[0];            this.returnKeys = false;        }        parameters = (ParamInfo[]) params.toArray(new ParamInfo[params.size()]);    }    /**     * This method converts native call syntax into (hopefully) valid JDBC escape syntax.     * NB. This method is required for backwards compatibility with previous versions of jTDS.     * Strictly speaking only the JDBC syntax needs to be recognised,     * constructions such as "?=#testproc ?,?" are neither valid native syntax nor valid escapes.     * All the substrings and trims below are not as bad as they look. The objects created all refer back     * to the original sql string it is just the start and length positions which change.     * @param sql The SQL statement to process.     * @return The SQL possibly in original form.     */    protected static String normalizeCall(String sql) {        String original = sql;        sql = sql.trim();        if (sql.length() > 0 && sql.charAt(0) == '{') {            return original; // Assume already escaped        }        if (sql.length() > 4 && sql.substring(0, 5).equalsIgnoreCase("exec ")) {            sql = sql.substring(4).trim();        } else if (sql.length() > 7 && sql.substring(0, 8).equalsIgnoreCase("execute ")){            sql = sql.substring(7).trim();        }        if (sql.length() > 1 && sql.charAt(0) == '?') {            sql = sql.substring(1).trim();            if (sql.length() < 1 || sql.charAt(0) != '=') {                return original; // Give up error will be reported elsewhere            }            sql = sql.substring(1).trim();            // OK now reconstruct as JDBC escaped call            return "{?=call " + sql + '}';        }        return "{call " + sql + '}';    }    /**     * Check that this statement is still open.     *     * @throws SQLException if statement closed.     */    protected void checkOpen() throws SQLException {        if (closed) {            throw new SQLException(                    Messages.get("error.generic.closed", "PreparedStatement"), "HY010");        }    }    /**     * Report that user tried to call a method not supported on this type of statement.     *     * @param method The method name to report in the error message.     * @throws SQLException     */    protected void notSupported(String method) throws SQLException {        throw new SQLException(                Messages.get("error.generic.notsup", method), "HYC00");    }    /**     * Executes a <code>ParamInfo</code> array (list of parameters).     *     * @param value list of parameters to execute     * @param last  <code>true</code> if this is the last parameter list in the     *              batch     */    protected void executeBatchOther(Object value, boolean last)            throws SQLException {        if (value instanceof ParamInfo[]) {            // procName will contain the procedure name for CallableStatements            // and null for PreparedStatements            tds.executeSQL(sql, procName, (ParamInfo[])value, false, 0, -1, -1, last);        } else {            super.executeBatchOther(value, last);        }    }/*    protected int executeBatchOther(Object value) throws SQLException {        if (value instanceof ParamInfo[]) {            ParamInfo[] saveParameters = parameters;            try {                parameters = (ParamInfo[]) value;                return executeUpdate();            } finally {                parameters = saveParameters;            }        }        super.executeBatchOther(value);        return Integer.MIN_VALUE;    }*/    /**     * Check the supplied index and return the selected parameter.     *     * @param parameterIndex the parameter index 1 to n.     * @return the parameter as a <code>ParamInfo</code> object.     * @throws SQLException if the statement is closed;     *                      if <code>parameterIndex</code> is less than 0;     *                      if <code>parameterIndex</code> is greater than the     *                      number of parameters;     *                      if <code>checkIfSet</code> was <code>true</code>     *                      and the parameter was not set     */    protected ParamInfo getParameter(int parameterIndex) throws SQLException {        checkOpen();        if (parameterIndex < 1 || parameterIndex > parameters.length) {            throw new SQLException(Messages.get("error.prepare.paramindex",                                                      Integer.toString(parameterIndex)),                                                      "07009");        }        ParamInfo pi = parameters[parameterIndex - 1];        return pi;    }    /**     * Generic setObject method.     *     * @param parameterIndex Parameter index 1 to n.     * @param x The value to set.     * @param targetSqlType The java.sql.Types constant describing the data.     * @param scale The decimal scale -1 if not set.     */    public void setObjectBase(int parameterIndex, Object x, int targetSqlType, int scale)            throws SQLException {        checkOpen();        int length = 0;        if (targetSqlType == java.sql.Types.CLOB) {            targetSqlType = java.sql.Types.LONGVARCHAR;        } else if (targetSqlType == java.sql.Types.BLOB) {            targetSqlType = java.sql.Types.LONGVARBINARY;        }        if (x != null) {            x = Support.convert(this, x, targetSqlType, connection.getCharset());            if (scale >= 0) {                if (x instanceof BigDecimal) {                    x = ((BigDecimal) x).setScale(scale, BigDecimal.ROUND_HALF_UP);                } else if (x instanceof Number) {                    synchronized (f) {                        f.setGroupingUsed(false);                        f.setMaximumFractionDigits(scale);                        x = Support.convert(this, f.format(x), targetSqlType,                                connection.getCharset());                    }                }            }            if (x instanceof Blob) {                Blob blob = (Blob) x;                length = (int) blob.length();                x = blob.getBinaryStream();            } else if (x instanceof Clob) {                Clob clob = (Clob) x;                length = (int) clob.length();                x = clob.getCharacterStream();            }        }        setParameter(parameterIndex, x, targetSqlType, scale, length);    }    /**     * Update the ParamInfo object for the specified parameter.     *     * @param parameterIndex Parameter index 1 to n.     * @param x The value to set.     * @param targetSqlType The java.sql.Types constant describing the data.     * @param scale The decimal scale -1 if not set.     * @param length The length of the data item.     */    protected void setParameter(int parameterIndex, Object x, int targetSqlType, int scale, int length)        throws SQLException {        ParamInfo pi = getParameter(parameterIndex);        if (Support.getJdbcTypeName(targetSqlType).equals("ERROR")) {            throw new SQLException(Messages.get("error.generic.badtype",                                Integer.toString(targetSqlType)), "HY092");        }        pi.scale = (scale < 0) ? 0 : scale;        // Update parameter descriptor        if (targetSqlType == java.sql.Types.DECIMAL            || targetSqlType == java.sql.Types.NUMERIC) {            pi.precision = connection.getMaxPrecision();            if (x instanceof BigDecimal) {                x = Support.normalizeBigDecimal((BigDecimal) x, pi.precision);                pi.scale = ((BigDecimal) x).scale();            }        }        if (x instanceof String) {            pi.length = ((String) x).length();        } else if (x instanceof byte[]) {            pi.length = ((byte[]) x).length;        } else {            pi.length   = length;        }        if (x instanceof Date) {            x = new DateTime((Date) x);        } else if (x instanceof Time) {            x = new DateTime((Time) x);        } else if (x instanceof Timestamp) {            x = new DateTime((Timestamp) x);        }        pi.value = x;        pi.jdbcType = targetSqlType;        pi.isSet = true;        pi.isUnicode = connection.isUseUnicode();    }    /**     * Update the cached column meta data information.     *     * @param value The Column meta data array.     */    void setColMetaData(ColInfo[] value) {        this.colMetaData = value;    }    /**     * Update the cached parameter meta data information.     *     * @param value The Column meta data array.     */    void setParamMetaData(ParamInfo[] value) {        for (int i = 0; i < value.length && i < parameters.length; i++) {            if (!parameters[i].isSet) {                // Only update parameter descriptors if the user                // has not yet set them.                parameters[i].jdbcType = value[i].jdbcType;                parameters[i].isOutput = value[i].isOutput;                parameters[i].precision = value[i].precision;                parameters[i].scale = value[i].scale;                parameters[i].sqlType = value[i].sqlType;            }        }    }// -------------------- java.sql.PreparedStatement methods follow -----------------    public int executeUpdate() throws SQLException {        checkOpen();        initialize();        if (procName == null && !(this instanceof JtdsCallableStatement)) {            // Sync on the connection to make sure rollback() isn't called            // between the moment when the statement is prepared and the moment            // when it's executed.            synchronized (connection) {                String spName = connection.prepareSQL(this, sql, parameters, returnKeys, false);                executeSQL(sql, spName, parameters, returnKeys, true, false);            }        } else {            executeSQL(sql, procName, parameters, returnKeys, true, false);        }        int res = getUpdateCount();        return res == -1 ? 0 : res;    }

⌨️ 快捷键说明

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