Source Code Cross Referenced for JtdsPreparedStatement.java in  » Database-JDBC-Connection-Pool » jTDS » net » sourceforge » jtds » jdbc » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database JDBC Connection Pool » jTDS » net.sourceforge.jtds.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // jTDS JDBC Driver for Microsoft SQL Server and Sybase
002:        // Copyright (C) 2004 The jTDS Project
003:        //
004:        // This library is free software; you can redistribute it and/or
005:        // modify it under the terms of the GNU Lesser General Public
006:        // License as published by the Free Software Foundation; either
007:        // version 2.1 of the License, or (at your option) any later version.
008:        //
009:        // This library is distributed in the hope that it will be useful,
010:        // but WITHOUT ANY WARRANTY; without even the implied warranty of
011:        // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012:        // Lesser General Public License for more details.
013:        //
014:        // You should have received a copy of the GNU Lesser General Public
015:        // License along with this library; if not, write to the Free Software
016:        // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
017:        //
018:        package net.sourceforge.jtds.jdbc;
019:
020:        import java.io.InputStream;
021:        import java.io.Reader;
022:        import java.math.BigDecimal;
023:        import java.net.URL;
024:        import java.sql.Array;
025:        import java.sql.Blob;
026:        import java.sql.Clob;
027:        import java.sql.Date;
028:        import java.sql.ParameterMetaData;
029:        import java.sql.PreparedStatement;
030:        import java.sql.Ref;
031:        import java.sql.ResultSet;
032:        import java.sql.ResultSetMetaData;
033:        import java.sql.SQLException;
034:        import java.sql.Time;
035:        import java.sql.Timestamp;
036:        import java.util.Calendar;
037:        import java.util.ArrayList;
038:        import java.util.Collection;
039:        import java.io.InputStreamReader;
040:        import java.io.UnsupportedEncodingException;
041:        import java.lang.reflect.Constructor;
042:        import java.text.NumberFormat;
043:
044:        /**
045:         * jTDS implementation of the java.sql.PreparedStatement interface.
046:         * <p>
047:         * Implementation notes:
048:         * <ol>
049:         * <li>Generally a simple subclass of Statement mainly adding support for the
050:         *     setting of parameters.
051:         * <li>The stream logic is taken over from the work Brian did to add Blob support
052:         *     to the original jTDS.
053:         * <li>Use of Statement specific method calls eg executeQuery(sql) is blocked by
054:         *     this version of the driver. This is unlike the original jTDS but inline
055:         *     with all the other JDBC drivers that I have been able to test.
056:         * </ol>
057:         *
058:         * @author Mike Hutchinson
059:         * @author Brian Heineman
060:         * @version $Id: JtdsPreparedStatement.java,v 1.63 2007/07/12 21:03:23 bheineman Exp $
061:         */
062:        public class JtdsPreparedStatement extends JtdsStatement implements 
063:                PreparedStatement {
064:            /** The SQL statement being prepared. */
065:            protected final String sql;
066:            /** The first SQL keyword in the SQL string.*/
067:            protected String sqlWord;
068:            /** The procedure name for CallableStatements. */
069:            protected String procName;
070:            /** The parameter list for the call. */
071:            protected ParamInfo[] parameters;
072:            /** True to return generated keys. */
073:            private boolean returnKeys;
074:            /** The cached parameter meta data. */
075:            protected ParamInfo[] paramMetaData;
076:            /** Used to format numeric values when scale is specified. */
077:            private final static NumberFormat f = NumberFormat.getInstance();
078:            /** Collection of handles used by this statement */
079:            Collection handles;
080:
081:            /**
082:             * Construct a new preparedStatement object.
083:             *
084:             * @param connection The parent connection.
085:             * @param sql   The SQL statement to prepare.
086:             * @param resultSetType The result set type eg SCROLLABLE etc.
087:             * @param concurrency The result set concurrency eg READONLY.
088:             * @param returnKeys True if generated keys should be returned.
089:             * @throws SQLException
090:             */
091:            JtdsPreparedStatement(ConnectionJDBC2 connection, String sql,
092:                    int resultSetType, int concurrency, boolean returnKeys)
093:                    throws SQLException {
094:                super (connection, resultSetType, concurrency);
095:
096:                // Parse the SQL looking for escapes and parameters
097:                if (this  instanceof  JtdsCallableStatement) {
098:                    sql = normalizeCall(sql);
099:                }
100:
101:                ArrayList params = new ArrayList();
102:                String[] parsedSql = SQLParser.parse(sql, params, connection,
103:                        false);
104:
105:                if (parsedSql[0].length() == 0) {
106:                    throw new SQLException(Messages.get("error.prepare.nosql"),
107:                            "07000");
108:                }
109:
110:                if (parsedSql[1].length() > 1) {
111:                    if (this  instanceof  JtdsCallableStatement) {
112:                        // Procedure call
113:                        this .procName = parsedSql[1];
114:                    }
115:                }
116:                sqlWord = parsedSql[2];
117:
118:                if (returnKeys && "insert".equals(sqlWord)) {
119:                    if (connection.getServerType() == Driver.SQLSERVER
120:                            && connection.getDatabaseMajorVersion() >= 8) {
121:                        this .sql = parsedSql[0]
122:                                + " SELECT SCOPE_IDENTITY() AS ID";
123:                    } else {
124:                        this .sql = parsedSql[0] + " SELECT @@IDENTITY AS ID";
125:                    }
126:                    this .returnKeys = true;
127:                } else {
128:                    this .sql = parsedSql[0];
129:                    this .returnKeys = false;
130:                }
131:
132:                parameters = (ParamInfo[]) params.toArray(new ParamInfo[params
133:                        .size()]);
134:            }
135:
136:            /**
137:             * This method converts native call syntax into (hopefully) valid JDBC
138:             * escape syntax.
139:             * <p/>
140:             * <b>Note:</b> This method is required for backwards compatibility with
141:             * previous versions of jTDS. Strictly speaking only the JDBC syntax needs
142:             * to be recognised, constructions such as "?=#testproc ?,?" are neither
143:             * valid native syntax nor valid escapes. All the substrings and trims
144:             * below are not as bad as they look. The objects created all refer back to
145:             * the original sql string it is just the start and length positions which
146:             * change.
147:             *
148:             * @param sql the SQL statement to process
149:             * @return the SQL, possibly in original form
150:             */
151:            protected static String normalizeCall(String sql) {
152:                String original = sql;
153:                sql = sql.trim();
154:
155:                if (sql.length() > 0 && sql.charAt(0) == '{') {
156:                    return original; // Assume already escaped
157:                }
158:
159:                if (sql.length() > 4
160:                        && sql.substring(0, 5).equalsIgnoreCase("exec ")) {
161:                    sql = sql.substring(4).trim();
162:                } else if (sql.length() > 7
163:                        && sql.substring(0, 8).equalsIgnoreCase("execute ")) {
164:                    sql = sql.substring(7).trim();
165:                }
166:
167:                if (sql.length() > 1 && sql.charAt(0) == '?') {
168:                    sql = sql.substring(1).trim();
169:
170:                    if (sql.length() < 1 || sql.charAt(0) != '=') {
171:                        return original; // Give up, error will be reported elsewhere
172:                    }
173:
174:                    sql = sql.substring(1).trim();
175:
176:                    // OK now reconstruct as JDBC escaped call
177:                    return "{?=call " + sql + '}';
178:                }
179:
180:                return "{call " + sql + '}';
181:            }
182:
183:            /**
184:             * Check that this statement is still open.
185:             *
186:             * @throws SQLException if statement closed.
187:             */
188:            protected void checkOpen() throws SQLException {
189:                if (closed) {
190:                    throw new SQLException(Messages.get("error.generic.closed",
191:                            "PreparedStatement"), "HY010");
192:                }
193:            }
194:
195:            /**
196:             * Report that user tried to call a method not supported on this type of statement.
197:             *
198:             * @param method The method name to report in the error message.
199:             * @throws SQLException
200:             */
201:            protected void notSupported(String method) throws SQLException {
202:                throw new SQLException(Messages.get("error.generic.notsup",
203:                        method), "HYC00");
204:            }
205:
206:            /**
207:             * Execute the SQL batch on a MS server.
208:             * <p/>
209:             * When running with <code>prepareSQL=1</code> or <code>3</code>, the driver will first prepare temporary stored
210:             * procedures or statements for each parameter combination found in the batch. The handles to these pre-preared
211:             * statements will then be used to execute the actual batch statements.
212:             *
213:             * @param size        the total size of the batch
214:             * @param executeSize the maximum number of statements to send in one request
215:             * @param counts      the returned update counts
216:             * @return chained exceptions linked to a <code>SQLException</code>
217:             * @throws SQLException if a serious error occurs during execution
218:             */
219:            protected SQLException executeMSBatch(int size, int executeSize,
220:                    ArrayList counts) throws SQLException {
221:                if (parameters.length == 0) {
222:                    // There are no parameters, each SQL call is the same so execute as a simple batch
223:                    return super .executeMSBatch(size, executeSize, counts);
224:                }
225:                SQLException sqlEx = null;
226:                String procHandle[] = null;
227:
228:                // Prepare any statements before executing the batch
229:                if (connection.getPrepareSql() == TdsCore.TEMPORARY_STORED_PROCEDURES
230:                        || connection.getPrepareSql() == TdsCore.PREPARE) {
231:                    procHandle = new String[size];
232:                    for (int i = 0; i < size; i++) {
233:                        // Prepare the statement
234:                        procHandle[i] = connection.prepareSQL(this , sql,
235:                                (ParamInfo[]) batchValues.get(i), false, false);
236:                    }
237:                }
238:
239:                for (int i = 0; i < size;) {
240:                    Object value = batchValues.get(i);
241:                    if (procHandle != null) {
242:                        procName = procHandle[i];
243:                    }
244:                    ++i;
245:                    // Execute batch now if max size reached or end of batch
246:                    boolean executeNow = (i % executeSize == 0) || i == size;
247:
248:                    tds.startBatch();
249:                    tds.executeSQL(sql, procName, (ParamInfo[]) value, false,
250:                            0, -1, -1, executeNow);
251:
252:                    // If the batch has been sent, process the results
253:                    if (executeNow) {
254:                        sqlEx = tds.getBatchCounts(counts, sqlEx);
255:
256:                        // If a serious error then we stop execution now as count
257:                        // is too small.
258:                        if (sqlEx != null && counts.size() != i) {
259:                            break;
260:                        }
261:                    }
262:                }
263:                return sqlEx;
264:            }
265:
266:            /**
267:             * Execute the SQL batch on a Sybase server.
268:             * <p/>
269:             * Sybase needs to have the SQL concatenated into one TDS language packet followed by up to 1000 parameters. This
270:             * method will be overriden for <code>CallableStatements</code>.
271:             *
272:             * @param size the total size of the batch
273:             * @param executeSize the maximum number of statements to send in one request
274:             * @param counts the returned update counts
275:             * @return chained exceptions linked to a <code>SQLException</code>
276:             * @throws SQLException if a serious error occurs during execution
277:             */
278:            protected SQLException executeSybaseBatch(int size,
279:                    int executeSize, ArrayList counts) throws SQLException {
280:                if (parameters.length == 0) {
281:                    // There are no parameters each SQL call is the same so
282:                    // execute as a simple batch
283:                    return super .executeSybaseBatch(size, executeSize, counts);
284:                }
285:                // Revise the executeSize down if too many parameters will be required.
286:                // Be conservative the actual maximums are 256 for older servers and 2048.
287:                int maxParams = (connection.getDatabaseMajorVersion() < 12 || (connection
288:                        .getDatabaseMajorVersion() == 12 && connection
289:                        .getDatabaseMinorVersion() < 50)) ? 200 : 1000;
290:                StringBuffer sqlBuf = new StringBuffer(size * 32);
291:                SQLException sqlEx = null;
292:                if (parameters.length * executeSize > maxParams) {
293:                    executeSize = maxParams / parameters.length;
294:                    if (executeSize == 0) {
295:                        executeSize = 1;
296:                    }
297:                }
298:                ArrayList paramList = new ArrayList();
299:                for (int i = 0; i < size;) {
300:                    Object value = batchValues.get(i);
301:                    ++i;
302:                    // Execute batch now if max size reached or end of batch
303:                    boolean executeNow = (i % executeSize == 0) || i == size;
304:
305:                    int offset = sqlBuf.length();
306:                    sqlBuf.append(sql).append(' ');
307:                    for (int n = 0; n < parameters.length; n++) {
308:                        ParamInfo p = ((ParamInfo[]) value)[n];
309:                        // Allow for the position of the '?' marker in the buffer
310:                        p.markerPos += offset;
311:                        paramList.add(p);
312:                    }
313:                    if (executeNow) {
314:                        ParamInfo args[];
315:                        args = (ParamInfo[]) paramList
316:                                .toArray(new ParamInfo[paramList.size()]);
317:                        tds.executeSQL(sqlBuf.toString(), null, args, false, 0,
318:                                -1, -1, true);
319:                        sqlBuf.setLength(0);
320:                        paramList.clear();
321:                        // If the batch has been sent, process the results
322:                        sqlEx = tds.getBatchCounts(counts, sqlEx);
323:
324:                        // If a serious error or a server error then we stop
325:                        // execution now as count is too small.
326:                        if (sqlEx != null && counts.size() != i) {
327:                            break;
328:                        }
329:                    }
330:                }
331:                return sqlEx;
332:            }
333:
334:            /**
335:             * Check the supplied index and return the selected parameter.
336:             *
337:             * @param parameterIndex the parameter index 1 to n.
338:             * @return the parameter as a <code>ParamInfo</code> object.
339:             * @throws SQLException if the statement is closed;
340:             *                      if <code>parameterIndex</code> is less than 0;
341:             *                      if <code>parameterIndex</code> is greater than the
342:             *                      number of parameters;
343:             *                      if <code>checkIfSet</code> was <code>true</code>
344:             *                      and the parameter was not set
345:             */
346:            protected ParamInfo getParameter(int parameterIndex)
347:                    throws SQLException {
348:                checkOpen();
349:
350:                if (parameterIndex < 1 || parameterIndex > parameters.length) {
351:                    throw new SQLException(Messages.get(
352:                            "error.prepare.paramindex", Integer
353:                                    .toString(parameterIndex)), "07009");
354:                }
355:
356:                return parameters[parameterIndex - 1];
357:            }
358:
359:            /**
360:             * Generic setObject method.
361:             *
362:             * @param parameterIndex Parameter index 1 to n.
363:             * @param x The value to set.
364:             * @param targetSqlType The java.sql.Types constant describing the data.
365:             * @param scale The decimal scale -1 if not set.
366:             */
367:            public void setObjectBase(int parameterIndex, Object x,
368:                    int targetSqlType, int scale) throws SQLException {
369:                checkOpen();
370:
371:                int length = 0;
372:
373:                if (targetSqlType == java.sql.Types.CLOB) {
374:                    targetSqlType = java.sql.Types.LONGVARCHAR;
375:                } else if (targetSqlType == java.sql.Types.BLOB) {
376:                    targetSqlType = java.sql.Types.LONGVARBINARY;
377:                }
378:
379:                if (x != null) {
380:                    x = Support.convert(this , x, targetSqlType, connection
381:                            .getCharset());
382:
383:                    if (scale >= 0) {
384:                        if (x instanceof  BigDecimal) {
385:                            x = ((BigDecimal) x).setScale(scale,
386:                                    BigDecimal.ROUND_HALF_UP);
387:                        } else if (x instanceof  Number) {
388:                            synchronized (f) {
389:                                f.setGroupingUsed(false);
390:                                f.setMaximumFractionDigits(scale);
391:                                x = Support.convert(this , f.format(x),
392:                                        targetSqlType, connection.getCharset());
393:                            }
394:                        }
395:                    }
396:
397:                    if (x instanceof  Blob) {
398:                        Blob blob = (Blob) x;
399:                        length = (int) blob.length();
400:                        x = blob.getBinaryStream();
401:                    } else if (x instanceof  Clob) {
402:                        Clob clob = (Clob) x;
403:                        length = (int) clob.length();
404:                        x = clob.getCharacterStream();
405:                    }
406:                }
407:
408:                setParameter(parameterIndex, x, targetSqlType, scale, length);
409:            }
410:
411:            /**
412:             * Update the ParamInfo object for the specified parameter.
413:             *
414:             * @param parameterIndex Parameter index 1 to n.
415:             * @param x The value to set.
416:             * @param targetSqlType The java.sql.Types constant describing the data.
417:             * @param scale The decimal scale -1 if not set.
418:             * @param length The length of the data item.
419:             */
420:            protected void setParameter(int parameterIndex, Object x,
421:                    int targetSqlType, int scale, int length)
422:                    throws SQLException {
423:                ParamInfo pi = getParameter(parameterIndex);
424:
425:                if ("ERROR".equals(Support.getJdbcTypeName(targetSqlType))) {
426:                    throw new SQLException(Messages.get(
427:                            "error.generic.badtype", Integer
428:                                    .toString(targetSqlType)), "HY092");
429:                }
430:
431:                // Update parameter descriptor
432:                if (targetSqlType == java.sql.Types.DECIMAL
433:                        || targetSqlType == java.sql.Types.NUMERIC) {
434:
435:                    pi.precision = connection.getMaxPrecision();
436:                    if (x instanceof  BigDecimal) {
437:                        x = Support.normalizeBigDecimal((BigDecimal) x,
438:                                pi.precision);
439:                        pi.scale = ((BigDecimal) x).scale();
440:                    } else {
441:                        pi.scale = (scale < 0) ? TdsData.DEFAULT_SCALE : scale;
442:                    }
443:                } else {
444:                    pi.scale = (scale < 0) ? 0 : scale;
445:                }
446:
447:                if (x instanceof  String) {
448:                    pi.length = ((String) x).length();
449:                } else if (x instanceof  byte[]) {
450:                    pi.length = ((byte[]) x).length;
451:                } else {
452:                    pi.length = length;
453:                }
454:
455:                if (x instanceof  Date) {
456:                    x = new DateTime((Date) x);
457:                } else if (x instanceof  Time) {
458:                    x = new DateTime((Time) x);
459:                } else if (x instanceof  Timestamp) {
460:                    x = new DateTime((Timestamp) x);
461:                }
462:
463:                pi.value = x;
464:                pi.jdbcType = targetSqlType;
465:                pi.isSet = true;
466:                pi.isUnicode = connection.getUseUnicode();
467:            }
468:
469:            /**
470:             * Update the cached column meta data information.
471:             *
472:             * @param value The Column meta data array.
473:             */
474:            void setColMetaData(ColInfo[] value) {
475:                this .colMetaData = value;
476:            }
477:
478:            /**
479:             * Update the cached parameter meta data information.
480:             *
481:             * @param value The Column meta data array.
482:             */
483:            void setParamMetaData(ParamInfo[] value) {
484:                for (int i = 0; i < value.length && i < parameters.length; i++) {
485:                    if (!parameters[i].isSet) {
486:                        // Only update parameter descriptors if the user
487:                        // has not yet set them.
488:                        parameters[i].jdbcType = value[i].jdbcType;
489:                        parameters[i].isOutput = value[i].isOutput;
490:                        parameters[i].precision = value[i].precision;
491:                        parameters[i].scale = value[i].scale;
492:                        parameters[i].sqlType = value[i].sqlType;
493:                    }
494:                }
495:            }
496:
497:            // -------------------- java.sql.PreparedStatement methods follow -----------------
498:
499:            public void close() throws SQLException {
500:                try {
501:                    super .close();
502:                } finally {
503:                    // Null these fields to reduce memory usage while
504:                    // wating for Statement.finalize() to execute.
505:                    this .handles = null;
506:                    this .parameters = null;
507:                }
508:            }
509:
510:            public int executeUpdate() throws SQLException {
511:                checkOpen();
512:                initialize();
513:
514:                if (procName == null
515:                        && !(this  instanceof  JtdsCallableStatement)) {
516:                    // Sync on the connection to make sure rollback() isn't called
517:                    // between the moment when the statement is prepared and the moment
518:                    // when it's executed.
519:                    synchronized (connection) {
520:                        String spName = connection.prepareSQL(this , sql,
521:                                parameters, returnKeys, false);
522:                        executeSQL(sql, spName, parameters, returnKeys, true,
523:                                false);
524:                    }
525:                } else {
526:                    executeSQL(sql, procName, parameters, returnKeys, true,
527:                            false);
528:                }
529:
530:                int res = getUpdateCount();
531:                return res == -1 ? 0 : res;
532:            }
533:
534:            public void addBatch() throws SQLException {
535:                checkOpen();
536:
537:                if (batchValues == null) {
538:                    batchValues = new ArrayList();
539:                }
540:
541:                if (parameters.length == 0) {
542:                    // This is likely to be an error. Batch execution
543:                    // of a prepared statement with no parameters means
544:                    // exactly the same SQL will be executed each time!
545:                    batchValues.add(sql);
546:                } else {
547:                    batchValues.add(parameters);
548:
549:                    ParamInfo tmp[] = new ParamInfo[parameters.length];
550:
551:                    for (int i = 0; i < parameters.length; ++i) {
552:                        tmp[i] = (ParamInfo) parameters[i].clone();
553:                    }
554:
555:                    parameters = tmp;
556:                }
557:            }
558:
559:            public void clearParameters() throws SQLException {
560:                checkOpen();
561:
562:                for (int i = 0; i < parameters.length; i++) {
563:                    parameters[i].clearInValue();
564:                }
565:            }
566:
567:            public boolean execute() throws SQLException {
568:                checkOpen();
569:                initialize();
570:                boolean useCursor = useCursor(returnKeys, sqlWord);
571:
572:                if (procName == null
573:                        && !(this  instanceof  JtdsCallableStatement)) {
574:                    // Sync on the connection to make sure rollback() isn't called
575:                    // between the moment when the statement is prepared and the moment
576:                    // when it's executed.
577:                    synchronized (connection) {
578:                        String spName = connection.prepareSQL(this , sql,
579:                                parameters, returnKeys, useCursor);
580:                        return executeSQL(sql, spName, parameters, returnKeys,
581:                                false, useCursor);
582:                    }
583:                } else {
584:                    return executeSQL(sql, procName, parameters, returnKeys,
585:                            false, useCursor);
586:                }
587:            }
588:
589:            public void setByte(int parameterIndex, byte x) throws SQLException {
590:                setParameter(parameterIndex, new Integer((int) (x & 0xFF)),
591:                        java.sql.Types.TINYINT, 0, 0);
592:            }
593:
594:            public void setDouble(int parameterIndex, double x)
595:                    throws SQLException {
596:                setParameter(parameterIndex, new Double(x),
597:                        java.sql.Types.DOUBLE, 0, 0);
598:            }
599:
600:            public void setFloat(int parameterIndex, float x)
601:                    throws SQLException {
602:                setParameter(parameterIndex, new Float(x), java.sql.Types.REAL,
603:                        0, 0);
604:            }
605:
606:            public void setInt(int parameterIndex, int x) throws SQLException {
607:                setParameter(parameterIndex, new Integer(x),
608:                        java.sql.Types.INTEGER, 0, 0);
609:            }
610:
611:            public void setNull(int parameterIndex, int sqlType)
612:                    throws SQLException {
613:                if (sqlType == java.sql.Types.CLOB) {
614:                    sqlType = java.sql.Types.LONGVARCHAR;
615:                } else if (sqlType == java.sql.Types.BLOB) {
616:                    sqlType = java.sql.Types.LONGVARBINARY;
617:                }
618:
619:                setParameter(parameterIndex, null, sqlType, -1, 0);
620:            }
621:
622:            public void setLong(int parameterIndex, long x) throws SQLException {
623:                setParameter(parameterIndex, new Long(x),
624:                        java.sql.Types.BIGINT, 0, 0);
625:            }
626:
627:            public void setShort(int parameterIndex, short x)
628:                    throws SQLException {
629:                setParameter(parameterIndex, new Integer(x),
630:                        java.sql.Types.SMALLINT, 0, 0);
631:            }
632:
633:            public void setBoolean(int parameterIndex, boolean x)
634:                    throws SQLException {
635:                setParameter(parameterIndex, x ? Boolean.TRUE : Boolean.FALSE,
636:                        BOOLEAN, 0, 0);
637:            }
638:
639:            public void setBytes(int parameterIndex, byte[] x)
640:                    throws SQLException {
641:                setParameter(parameterIndex, x, java.sql.Types.BINARY, 0, 0);
642:            }
643:
644:            public void setAsciiStream(int parameterIndex,
645:                    InputStream inputStream, int length) throws SQLException {
646:                if (inputStream == null || length < 0) {
647:                    setParameter(parameterIndex, null,
648:                            java.sql.Types.LONGVARCHAR, 0, 0);
649:                } else {
650:                    try {
651:                        setCharacterStream(parameterIndex,
652:                                new InputStreamReader(inputStream, "US-ASCII"),
653:                                length);
654:                    } catch (UnsupportedEncodingException e) {
655:                        // Should never happen!
656:                    }
657:                }
658:            }
659:
660:            public void setBinaryStream(int parameterIndex, InputStream x,
661:                    int length) throws SQLException {
662:                checkOpen();
663:
664:                if (x == null || length < 0) {
665:                    setBytes(parameterIndex, null);
666:                } else {
667:                    setParameter(parameterIndex, x,
668:                            java.sql.Types.LONGVARBINARY, 0, length);
669:                }
670:            }
671:
672:            public void setUnicodeStream(int parameterIndex,
673:                    InputStream inputStream, int length) throws SQLException {
674:                checkOpen();
675:                if (inputStream == null || length < 0) {
676:                    setString(parameterIndex, null);
677:                } else {
678:                    try {
679:                        length /= 2;
680:                        char[] tmp = new char[length];
681:                        int pos = 0;
682:                        int b1 = inputStream.read();
683:                        int b2 = inputStream.read();
684:
685:                        while (b1 >= 0 && b2 >= 0 && pos < length) {
686:                            tmp[pos++] = (char) (((b1 << 8) & 0xFF00) | (b2 & 0xFF));
687:                            b1 = inputStream.read();
688:                            b2 = inputStream.read();
689:                        }
690:                        setString(parameterIndex, new String(tmp, 0, pos));
691:                    } catch (java.io.IOException e) {
692:                        throw new SQLException(Messages.get(
693:                                "error.generic.ioerror", e.getMessage()),
694:                                "HY000");
695:                    }
696:                }
697:            }
698:
699:            public void setCharacterStream(int parameterIndex, Reader reader,
700:                    int length) throws SQLException {
701:                if (reader == null || length < 0) {
702:                    setParameter(parameterIndex, null,
703:                            java.sql.Types.LONGVARCHAR, 0, 0);
704:                } else {
705:                    setParameter(parameterIndex, reader,
706:                            java.sql.Types.LONGVARCHAR, 0, length);
707:                }
708:            }
709:
710:            public void setObject(int parameterIndex, Object x)
711:                    throws SQLException {
712:                setObjectBase(parameterIndex, x, Support.getJdbcType(x), -1);
713:            }
714:
715:            public void setObject(int parameterIndex, Object x,
716:                    int targetSqlType) throws SQLException {
717:                setObjectBase(parameterIndex, x, targetSqlType, -1);
718:            }
719:
720:            public void setObject(int parameterIndex, Object x,
721:                    int targetSqlType, int scale) throws SQLException {
722:                checkOpen();
723:                if (scale < 0 || scale > connection.getMaxPrecision()) {
724:                    throw new SQLException(Messages
725:                            .get("error.generic.badscale"), "HY092");
726:                }
727:                setObjectBase(parameterIndex, x, targetSqlType, scale);
728:            }
729:
730:            public void setNull(int parameterIndex, int sqlType, String typeName)
731:                    throws SQLException {
732:                notImplemented("PreparedStatement.setNull(int, int, String)");
733:            }
734:
735:            public void setString(int parameterIndex, String x)
736:                    throws SQLException {
737:                setParameter(parameterIndex, x, java.sql.Types.VARCHAR, 0, 0);
738:            }
739:
740:            public void setBigDecimal(int parameterIndex, BigDecimal x)
741:                    throws SQLException {
742:                setParameter(parameterIndex, x, java.sql.Types.DECIMAL, -1, 0);
743:            }
744:
745:            public void setURL(int parameterIndex, URL url) throws SQLException {
746:                setString(parameterIndex, (url == null) ? null : url.toString());
747:            }
748:
749:            public void setArray(int arg0, Array arg1) throws SQLException {
750:                notImplemented("PreparedStatement.setArray");
751:            }
752:
753:            public void setBlob(int parameterIndex, Blob x) throws SQLException {
754:                if (x == null) {
755:                    setBytes(parameterIndex, null);
756:                } else {
757:                    long length = x.length();
758:
759:                    if (length > Integer.MAX_VALUE) {
760:                        throw new SQLException(Messages
761:                                .get("error.resultset.longblob"), "24000");
762:                    }
763:
764:                    setBinaryStream(parameterIndex, x.getBinaryStream(),
765:                            (int) x.length());
766:                }
767:            }
768:
769:            public void setClob(int parameterIndex, Clob x) throws SQLException {
770:                if (x == null) {
771:                    this .setString(parameterIndex, null);
772:                } else {
773:                    long length = x.length();
774:
775:                    if (length > Integer.MAX_VALUE) {
776:                        throw new SQLException(Messages
777:                                .get("error.resultset.longclob"), "24000");
778:                    }
779:
780:                    setCharacterStream(parameterIndex, x.getCharacterStream(),
781:                            (int) x.length());
782:                }
783:            }
784:
785:            public void setDate(int parameterIndex, Date x) throws SQLException {
786:                setParameter(parameterIndex, x, java.sql.Types.DATE, 0, 0);
787:            }
788:
789:            public ParameterMetaData getParameterMetaData() throws SQLException {
790:                checkOpen();
791:
792:                //
793:                // NB. This is usable only with the JDBC3 version of the interface.
794:                //
795:                if (connection.getServerType() == Driver.SYBASE) {
796:                    // Sybase does return the parameter types for prepared sql.
797:                    connection.prepareSQL(this , sql, new ParamInfo[0], false,
798:                            false);
799:                }
800:
801:                try {
802:                    Class pmdClass = Class
803:                            .forName("net.sourceforge.jtds.jdbc.ParameterMetaDataImpl");
804:                    Class[] parameterTypes = new Class[] { ParamInfo[].class,
805:                            ConnectionJDBC2.class };
806:                    Object[] arguments = new Object[] { parameters, connection };
807:                    Constructor pmdConstructor = pmdClass
808:                            .getConstructor(parameterTypes);
809:
810:                    return (ParameterMetaData) pmdConstructor
811:                            .newInstance(arguments);
812:                } catch (Exception e) {
813:                    notImplemented("PreparedStatement.getParameterMetaData");
814:                }
815:
816:                return null;
817:            }
818:
819:            public void setRef(int parameterIndex, Ref x) throws SQLException {
820:                notImplemented("PreparedStatement.setRef");
821:            }
822:
823:            public ResultSet executeQuery() throws SQLException {
824:                checkOpen();
825:                initialize();
826:                boolean useCursor = useCursor(false, null);
827:
828:                if (procName == null
829:                        && !(this  instanceof  JtdsCallableStatement)) {
830:                    // Sync on the connection to make sure rollback() isn't called
831:                    // between the moment when the statement is prepared and the moment
832:                    // when it's executed.
833:                    synchronized (connection) {
834:                        String spName = connection.prepareSQL(this , sql,
835:                                parameters, false, useCursor);
836:                        return executeSQLQuery(sql, spName, parameters,
837:                                useCursor);
838:                    }
839:                } else {
840:                    return executeSQLQuery(sql, procName, parameters, useCursor);
841:                }
842:            }
843:
844:            public ResultSetMetaData getMetaData() throws SQLException {
845:                checkOpen();
846:
847:                if (colMetaData == null) {
848:                    if (currentResult != null) {
849:                        colMetaData = currentResult.columns;
850:                    } else if (connection.getServerType() == Driver.SYBASE) {
851:                        // Sybase can provide meta data as a by product of preparing the call.
852:                        connection.prepareSQL(this , sql, new ParamInfo[0],
853:                                false, false);
854:
855:                        if (colMetaData == null) {
856:                            return null; // Sorry still no go
857:                        }
858:                    } else {
859:                        // For Microsoft set all parameters to null and execute the query.
860:                        // SET FMTONLY ON asks the server just to return meta data.
861:                        // This only works for select statements
862:                        if (!"select".equals(sqlWord)) {
863:                            return null;
864:                        }
865:
866:                        // Copy parameters to avoid corrupting any values already set
867:                        // by the user as we need to set a flag and null out the data.
868:                        ParamInfo[] params = new ParamInfo[parameters.length];
869:                        for (int i = 0; i < params.length; i++) {
870:                            params[i] = new ParamInfo(parameters[i].markerPos,
871:                                    false);
872:                            params[i].isSet = true;
873:                        }
874:
875:                        // Substitute nulls into SQL String
876:                        StringBuffer testSql = new StringBuffer(
877:                                sql.length() + 128);
878:                        testSql.append("SET FMTONLY ON ");
879:                        testSql.append(Support.substituteParameters(sql,
880:                                params, connection));
881:                        testSql.append(" SET FMTONLY OFF");
882:
883:                        try {
884:                            tds.submitSQL(testSql.toString());
885:                            colMetaData = tds.getColumns();
886:                        } catch (SQLException e) {
887:                            // Ensure FMTONLY is switched off!
888:                            tds.submitSQL("SET FMTONLY OFF");
889:                            return null;
890:                        }
891:                    }
892:                }
893:
894:                return new JtdsResultSetMetaData(colMetaData, JtdsResultSet
895:                        .getColumnCount(colMetaData), connection.getUseLOBs());
896:            }
897:
898:            public void setTime(int parameterIndex, Time x) throws SQLException {
899:                setParameter(parameterIndex, x, java.sql.Types.TIME, 0, 0);
900:            }
901:
902:            public void setTimestamp(int parameterIndex, Timestamp x)
903:                    throws SQLException {
904:                setParameter(parameterIndex, x, java.sql.Types.TIMESTAMP, 0, 0);
905:            }
906:
907:            public void setDate(int parameterIndex, Date x, Calendar cal)
908:                    throws SQLException {
909:
910:                if (x != null && cal != null) {
911:                    x = new java.sql.Date(Support.timeFromZone(x, cal));
912:                }
913:
914:                setDate(parameterIndex, x);
915:            }
916:
917:            public void setTime(int parameterIndex, Time x, Calendar cal)
918:                    throws SQLException {
919:
920:                if (x != null && cal != null) {
921:                    x = new Time(Support.timeFromZone(x, cal));
922:                }
923:
924:                setTime(parameterIndex, x);
925:            }
926:
927:            public void setTimestamp(int parameterIndex, Timestamp x,
928:                    Calendar cal) throws SQLException {
929:
930:                if (x != null && cal != null) {
931:                    x = new java.sql.Timestamp(Support.timeFromZone(x, cal));
932:                }
933:
934:                setTimestamp(parameterIndex, x);
935:            }
936:
937:            public int executeUpdate(String sql) throws SQLException {
938:                notSupported("executeUpdate(String)");
939:                return 0;
940:            }
941:
942:            public void addBatch(String sql) throws SQLException {
943:                notSupported("executeBatch(String)");
944:            }
945:
946:            public boolean execute(String sql) throws SQLException {
947:                notSupported("execute(String)");
948:                return false;
949:            }
950:
951:            public int executeUpdate(String sql, int getKeys)
952:                    throws SQLException {
953:                notSupported("executeUpdate(String, int)");
954:                return 0;
955:            }
956:
957:            public boolean execute(String arg0, int arg1) throws SQLException {
958:                notSupported("execute(String, int)");
959:                return false;
960:            }
961:
962:            public int executeUpdate(String arg0, int[] arg1)
963:                    throws SQLException {
964:                notSupported("executeUpdate(String, int[])");
965:                return 0;
966:            }
967:
968:            public boolean execute(String arg0, int[] arg1) throws SQLException {
969:                notSupported("execute(String, int[])");
970:                return false;
971:            }
972:
973:            public int executeUpdate(String arg0, String[] arg1)
974:                    throws SQLException {
975:                notSupported("executeUpdate(String, String[])");
976:                return 0;
977:            }
978:
979:            public boolean execute(String arg0, String[] arg1)
980:                    throws SQLException {
981:                notSupported("execute(String, String[])");
982:                return false;
983:            }
984:
985:            public ResultSet executeQuery(String sql) throws SQLException {
986:                notSupported("executeQuery(String)");
987:                return null;
988:            }
989:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.