1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package java.sql;
19
20/**
21 * Interface used for executing static SQL statements to retrieve query results.
22 * The resulting table rows are returned as {@code ResultSet}s. For any given
23 * {@code Statement} object, only one {@code ResultSet} can be opened at one
24 * time. A call to any of the execution methods of {@code Statement} will cause
25 * any previously created {@code ResultSet} object for that {@code Statement} to
26 * be closed implicitly.
27 * <p>
28 * To have multiple {@code ResultSet} objects opened concurrently, multiple
29 * {@code Statement} objects must be created and then executed.
30 * <p>
31 * To obtain such an executable statement one needs to invoke {@code
32 * Connection#createStatement}.
33 *
34 * @see ResultSet
35 * @see Connection#createStatement
36 */
37public interface Statement extends Wrapper, AutoCloseable {
38
39    /**
40     * Passing this constant to {@link #getMoreResults} implies that all {@code
41     * ResultSet} objects previously kept open should be closed.
42     */
43    public static final int CLOSE_ALL_RESULTS = 3;
44
45    /**
46     * Passing this constant to {@link #getMoreResults} implies that the current
47     * {@code ResultSet} object should be closed.
48     */
49    public static final int CLOSE_CURRENT_RESULT = 1;
50
51    /**
52     * Indicates that an error was encountered during execution of a batch
53     * statement.
54     */
55    public static final int EXECUTE_FAILED = -3;
56
57    /**
58     * Passing this constant to <i>getMoreResults</i> implies that the current
59     * {@code ResultSet} object should not be closed.
60     */
61    public static final int KEEP_CURRENT_RESULT = 2;
62
63    /**
64     * Indicates that generated keys should not be accessible for retrieval.
65     */
66    public static final int NO_GENERATED_KEYS = 2;
67
68    /**
69     * Indicates that generated keys should be accessible for retrieval.
70     */
71    public static final int RETURN_GENERATED_KEYS = 1;
72
73    /**
74     * Indicates that a batch statement was executed with a successful result,
75     * but a count of the number of rows it affected is unavailable.
76     */
77    public static final int SUCCESS_NO_INFO = -2;
78
79    /**
80     * Adds a specified SQL command to the list of commands for this {@code
81     * Statement}.
82     * <p>
83     * The list of commands is executed by invoking the {@code executeBatch}
84     * method.
85     *
86     * @param sql
87     *            the SQL command as a String. Typically an {@code INSERT} or
88     *            {@code UPDATE} statement.
89     * @throws SQLException
90     *             if an error occurs accessing the database or the database
91     *             does not support batch updates.
92     */
93    public void addBatch(String sql) throws SQLException;
94
95    /**
96     * Cancels this statement's execution if both the database and the JDBC
97     * driver support aborting an SQL statement in flight. This method can be
98     * used by one thread to stop a statement that is executed on another
99     * thread.
100     *
101     * @throws SQLException
102     *             if an error occurs accessing the database.
103     */
104    public void cancel() throws SQLException;
105
106    /**
107     * Clears the current list of SQL commands for this statement.
108     *
109     * @throws SQLException
110     *             if an error occurs accessing the database or the database
111     *             does not support batch updates.
112     */
113    public void clearBatch() throws SQLException;
114
115    /**
116     * Clears all {@code SQLWarnings} from this statement.
117     *
118     * @throws SQLException
119     *             if an error occurs accessing the database.
120     */
121    public void clearWarnings() throws SQLException;
122
123    /**
124     * Releases this statement's database and JDBC driver resources.
125     * <p>
126     * Using this method to release these resources as soon as possible is
127     * strongly recommended.
128     * <p>
129     * One should not rely on the resources being automatically released when
130     * finalized during garbage collection. Doing so can result in unpredictable
131     * behavior for the application.
132     *
133     * @throws SQLException
134     *             if an error occurs accessing the database.
135     */
136    public void close() throws SQLException;
137
138    /**
139     * Executes a supplied SQL statement. This may return multiple {@code
140     * ResultSet}s.
141     * <p>
142     * Use the {@code getResultSet} or {@code getUpdateCount} methods to get the
143     * first result and {@code getMoreResults} to get any subsequent results.
144     *
145     * @param sql
146     *            the SQL statement to execute
147     * @return {@code true} if the first result is a {@code ResultSet}, {@code
148     *         false} if the first result is an update count or if there is no
149     *         result.
150     * @throws SQLException
151     *             if an error occurs accessing the database.
152     */
153    public boolean execute(String sql) throws SQLException;
154
155    /**
156     * Executes a supplied SQL statement. This may return multiple {@code
157     * ResultSet}s. This method allows control of whether auto-generated Keys
158     * should be made available for retrieval, if the SQL statement is an
159     * {@code INSERT} statement.
160     * <p>
161     * Use the {@code getResultSet} or {@code getUpdateCount} methods to get the
162     * first result and {@code getMoreResults} to get any subsequent results.
163     *
164     * @param sql
165     *            the SQL statement to execute.
166     * @param autoGeneratedKeys
167     *            a flag indicating whether to make auto generated keys
168     *            available for retrieval. This parameter must be one of {@code
169     *            Statement.NO_GENERATED_KEYS} or {@code
170     *            Statement.RETURN_GENERATED_KEYS}.
171     * @return {@code true} if results exists and the first result is a {@code
172     *         ResultSet}, {@code false} if the first result is an update count
173     *         or if there is no result.
174     * @throws SQLException
175     *             if an error occurs accessing the database.
176     */
177    public boolean execute(String sql, int autoGeneratedKeys)
178            throws SQLException;
179
180    /**
181     * Executes the supplied SQL statement. This may return multiple {@code
182     * ResultSet}s. This method allows retrieval of auto generated keys
183     * specified by the supplied array of column indexes, if the SQL statement
184     * is an {@code INSERT} statement.
185     * <p>
186     * Use the {@code getResultSet} or {@code getUpdateCount} methods to get the
187     * first result and {@code getMoreResults} to get any subsequent results.
188     *
189     * @param sql
190     *            the SQL statement to execute.
191     * @param columnIndexes
192     *            an array of indexes of the columns in the inserted row which
193     *            should be made available for retrieval via the {@code
194     *            getGeneratedKeys} method.
195     * @return {@code true} if the first result is a {@code ResultSet}, {@code
196     *         false} if the first result is an update count or if there is no
197     *         result.
198     * @throws SQLException
199     *             if an error occurs accessing the database.
200     */
201    public boolean execute(String sql, int[] columnIndexes) throws SQLException;
202
203    /**
204     * Executes the supplied SQL statement. This may return multiple {@code
205     * ResultSet}s. This method allows retrieval of auto generated keys
206     * specified by the supplied array of column indexes, if the SQL statement
207     * is an {@code INSERT} statement.
208     * <p>
209     * Use the {@code getResultSet} or {@code getUpdateCount} methods to get the
210     * first result and {@code getMoreResults} to get any subsequent results.
211     *
212     * @param sql
213     *            the SQL statement to execute.
214     * @param columnNames
215     *            an array of column names in the inserted row which should be
216     *            made available for retrieval via the {@code getGeneratedKeys}
217     *            method.
218     * @return {@code true} if the first result is a {@code ResultSet}, {@code
219     *         false} if the first result is an update count or if there is no
220     *         result
221     * @throws SQLException
222     *             if an error occurs accessing the database.
223     */
224    public boolean execute(String sql, String[] columnNames)
225            throws SQLException;
226
227    /**
228     * Submits a batch of SQL commands to the database. Returns an array of
229     * update counts, if all the commands execute successfully.
230     * <p>
231     * If one of the commands in the batch fails, this method can throw a
232     * {@link BatchUpdateException} and the JDBC driver may or may not process
233     * the remaining commands. The JDBC driver must behave consistently with the
234     * underlying database, following the "all or nothing" principle. If the
235     * driver continues processing, the array of results returned contains the
236     * same number of elements as there are commands in the batch, with a
237     * minimum of one of the elements having the {@code EXECUTE_FAILED} value.
238     *
239     * @return an array of update counts, with one entry for each command in the
240     *         batch. The elements are ordered according to the order in which
241     *         the commands were added to the batch.
242     *         <p>
243     *         <ol>
244     *         <li>If the value of an element is &ge; 0, the corresponding
245     *         command completed successfully and the value is the <i>update
246     *         count</i> (the number of rows in the database affected by the
247     *         command) for that command.</li>
248     *         <li>If the value is {@code SUCCESS_NO_INFO}, the command
249     *         completed successfully but the number of rows affected is
250     *         unknown.
251     *         <li>
252     *         <li>If the value is {@code EXECUTE_FAILED}, the command failed.
253     *         </ol>
254     * @throws SQLException
255     *             if an error occurs accessing the database.
256     */
257    public int[] executeBatch() throws SQLException;
258
259    /**
260     * Executes a supplied SQL statement. Returns a single {@code ResultSet}.
261     *
262     * @param sql
263     *            an SQL statement to execute. Typically a {@code SELECT}
264     *            statement
265     * @return a {@code ResultSet} containing the data produced by the SQL
266     *         statement. Never null.
267     * @throws SQLException
268     *             if an error occurs accessing the database or if the statement
269     *             produces anything other than a single {@code ResultSet}.
270     */
271    public ResultSet executeQuery(String sql) throws SQLException;
272
273    /**
274     * Executes the supplied SQL statement. The statement may be an {@code
275     * INSERT}, {@code UPDATE} or {@code DELETE} statement or a statement which
276     * returns nothing.
277     *
278     * @param sql
279     *            an SQL statement to execute - an SQL {@code INSERT}, {@code
280     *            UPDATE}, {@code DELETE} or a statement which returns nothing
281     * @return the count of updated rows, or 0 for a statement that returns
282     *         nothing.
283     * @throws SQLException
284     *             if an error occurs accessing the database or if the statement
285     *             produces a {@code ResultSet}.
286     */
287    public int executeUpdate(String sql) throws SQLException;
288
289    /**
290     * Executes the supplied SQL statement. This method allows control of
291     * whether auto-generated Keys should be made available for retrieval.
292     *
293     * @param sql
294     *            an SQL statement to execute - an SQL {@code INSERT}, {@code
295     *            UPDATE}, {@code DELETE} or a statement which does not return
296     *            anything.
297     * @param autoGeneratedKeys
298     *            a flag that indicates whether to allow retrieval of auto
299     *            generated keys. Parameter must be one of {@code
300     *            Statement.RETURN_GENERATED_KEYS} or {@code
301     *            Statement.NO_GENERATED_KEYS}
302     * @return the number of updated rows, or 0 if the statement returns
303     *         nothing.
304     * @throws SQLException
305     *             if an error occurs accessing the database or if the statement
306     *             produces a {@code ResultSet}.
307     */
308    public int executeUpdate(String sql, int autoGeneratedKeys)
309            throws SQLException;
310
311    /**
312     * Executes the supplied SQL statement. This method allows retrieval of auto
313     * generated keys specified by the supplied array of column indexes.
314     *
315     * @param sql
316     *            an SQL statement to execute - an SQL {@code INSERT}, {@code
317     *            UPDATE}, {@code DELETE} or a statement which returns nothing
318     * @param columnIndexes
319     *            an array of indexes of the columns in the inserted row which
320     *            should be made available for retrieval via the {@code
321     *            getGeneratedKeys} method.
322     * @return the count of updated rows, or 0 for a statement that returns
323     *         nothing.
324     * @throws SQLException
325     *             if an error occurs accessing the database or if the statement
326     *             produces a {@code ResultSet}.
327     */
328    public int executeUpdate(String sql, int[] columnIndexes)
329            throws SQLException;
330
331    /**
332     * Executes the supplied SQL statement. This method allows retrieval of auto
333     * generated keys specified by the supplied array of column names.
334     *
335     * @param sql
336     *            an SQL statement to execute - an SQL {@code INSERT}, {@code
337     *            UPDATE}, {@code DELETE} or a statement which returns nothing
338     * @param columnNames
339     *            an array of column names in the inserted row which should be
340     *            made available for retrieval via the {@code getGeneratedKeys}
341     *            method.
342     * @return the count of updated rows, or 0 for a statement that returns
343     *         nothing.
344     * @throws SQLException
345     *             if an error occurs accessing the database or if the statement
346     *             produces a {@code ResultSet}.
347     */
348    public int executeUpdate(String sql, String[] columnNames)
349            throws SQLException;
350
351    /**
352     * Gets the {@code Connection} object which created this statement.
353     *
354     * @return the {@code Connection} through which this statement is
355     *         transmitted to the database.
356     * @throws SQLException
357     *             if an error occurs accessing the database.
358     */
359    public Connection getConnection() throws SQLException;
360
361    /**
362     * Gets the default direction for fetching rows for {@code ResultSet}s
363     * generated from this statement.
364     *
365     * @return the default fetch direction, one of:
366     *         <ul>
367     *         <li>ResultSet.FETCH_FORWARD</li> <li>ResultSet.FETCH_REVERSE</li>
368     *         <li>ResultSet.FETCH_UNKNOWN</li>
369     *         </ul>
370     * @throws SQLException
371     *             if an error occurs accessing the database.
372     */
373    public int getFetchDirection() throws SQLException;
374
375    /**
376     * Gets the default number of rows for a fetch for the {@code ResultSet}
377     * objects returned from this statement.
378     *
379     * @return the default fetch size for {@code ResultSet}s produced by this
380     *         statement.
381     * @throws SQLException
382     *             if an error occurs accessing the database.
383     */
384    public int getFetchSize() throws SQLException;
385
386    /**
387     * Returns auto generated keys created by executing this statement.
388     *
389     * @return a {@code ResultSet} containing the auto generated keys - empty if
390     *         no keys are generated by this statement.
391     * @throws SQLException
392     *             if an error occurs accessing the database.
393     */
394    public ResultSet getGeneratedKeys() throws SQLException;
395
396    /**
397     * Gets the maximum number of bytes which can be returned as values from
398     * character and binary type columns in a {@code ResultSet} derived from this
399     * statement. This limit applies to {@code BINARY}, {@code VARBINARY},
400     * {@code LONGVARBINARY}, {@code CHAR}, {@code VARCHAR}, and {@code
401     * LONGVARCHAR} types. Any data exceeding the maximum size is abandoned
402     * without announcement.
403     *
404     * @return the current size limit, where {@code 0} means that there is no
405     *         limit.
406     * @throws SQLException
407     *             if an error occurs accessing the database.
408     */
409    public int getMaxFieldSize() throws SQLException;
410
411    /**
412     * Gets the maximum number of rows that a {@code ResultSet} can contain when
413     * produced from this statement. If the limit is exceeded, the excess rows
414     * are discarded silently.
415     *
416     * @return the current row limit, where {@code 0} means that there is no
417     *         limit.
418     * @throws SQLException
419     *             if an error occurs accessing the database.
420     */
421    public int getMaxRows() throws SQLException;
422
423    /**
424     * Moves to this statement's next result. Returns {@code true} if it is a
425     * {@code ResultSet}. Any current {@code ResultSet} objects previously
426     * obtained with {@code getResultSet()} are closed implicitly.
427     *
428     * @return {@code true} if the next result is a {@code ResultSet}, {@code
429     *         false} if the next result is not a {@code ResultSet} or if there
430     *         are no more results. Note that if there is no more data, this
431     *         method will return {@code false} and {@code getUpdateCount} will
432     *         return -1.
433     * @throws SQLException
434     *             if an error occurs accessing the database.
435     */
436    public boolean getMoreResults() throws SQLException;
437
438    /**
439     * Moves to this statement's next result. Returns {@code true} if the next
440     * result is a {@code ResultSet}. Any current {@code ResultSet} objects
441     * previously obtained with {@code getResultSet()} are handled as indicated
442     * by a supplied Flag parameter.
443     *
444     * @param current
445     *            a flag indicating what to do with existing {@code ResultSet}s.
446     *            This parameter must be one of {@code
447     *            Statement.CLOSE_ALL_RESULTS}, {@code
448     *            Statement.CLOSE_CURRENT_RESULT} or {@code
449     *            Statement.KEEP_CURRENT_RESULT}.
450     * @return {@code true} if the next result exists and is a {@code ResultSet}
451     *         , {@code false} if the next result is not a {@code ResultSet} or
452     *         if there are no more results. Note that if there is no more data,
453     *         this method will return {@code false} and {@code getUpdateCount}
454     *         will return -1.
455     * @throws SQLException
456     *             if an error occurs accessing the database.
457     */
458    public boolean getMoreResults(int current) throws SQLException;
459
460    /**
461     * Gets the timeout value for the statement's execution time. The JDBC
462     * driver will wait up to this value for the execution to complete - after
463     * the limit is exceeded an SQL {@code Exception} is thrown.
464     *
465     * @return the current query timeout value, where {@code 0} indicates that
466     *         there is no current timeout.
467     * @throws SQLException
468     *             if an error occurs accessing the database.
469     */
470    public int getQueryTimeout() throws SQLException;
471
472    /**
473     * Gets the current result. Should only be called once per result.
474     *
475     * @return the {@code ResultSet} for the current result. {@code null} if the
476     *         result is an update count or if there are no more results.
477     * @throws SQLException
478     *             if an error occurs accessing the database.
479     */
480    public ResultSet getResultSet() throws SQLException;
481
482    /**
483     * Gets the concurrency setting for {@code ResultSet} objects generated by
484     * this statement.
485     *
486     * @return {@code ResultSet.CONCUR_READ_ONLY} or {@code
487     *         ResultSet.CONCUR_UPDATABLE}.
488     * @throws SQLException
489     *             if an error occurs accessing the database.
490     */
491    public int getResultSetConcurrency() throws SQLException;
492
493    /**
494     * Gets the cursor hold setting for {@code ResultSet} objects generated by
495     * this statement.
496     *
497     * @return {@code ResultSet.HOLD_CURSORS_OVER_COMMIT} or {@code
498     *         ResultSet.CLOSE_CURSORS_AT_COMMIT}
499     * @throws SQLException
500     *             if there is an error while accessing the database.
501     */
502    public int getResultSetHoldability() throws SQLException;
503
504    /**
505     * Gets the {@code ResultSet} type setting for {@code ResultSet}s derived
506     * from this statement.
507     *
508     * @return {@code ResultSet.TYPE_FORWARD_ONLY} for a {@code ResultSet} where
509     *         the cursor can only move forwards, {@code
510     *         ResultSet.TYPE_SCROLL_INSENSITIVE} for a {@code ResultSet} which
511     *         is scrollable but is not sensitive to changes made by others,
512     *         {@code ResultSet.TYPE_SCROLL_SENSITIVE} for a {@code ResultSet}
513     *         which is scrollable but is sensitive to changes made by others.
514     * @throws SQLException
515     *             if there is an error accessing the database.
516     */
517    public int getResultSetType() throws SQLException;
518
519    /**
520     * Gets an update count for the current result if it is not a {@code
521     * ResultSet}.
522     *
523     * @return the current result as an update count. {@code -1} if the current
524     *         result is a {@code ResultSet} or if there are no more results.
525     * @throws SQLException
526     *             if an error occurs accessing the database.
527     */
528    public int getUpdateCount() throws SQLException;
529
530    /**
531     * Retrieves the first {@code SQLWarning} reported by calls on this
532     * statement. If there are multiple warnings, subsequent warnings are
533     * chained to the first one. The chain of warnings is cleared each time the
534     * statement is executed.
535     * <p>
536     * Warnings associated with reads from the {@code ResultSet} returned from
537     * executing the statement will be attached to the {@code ResultSet}, not the
538     * statement object.
539     *
540     * @return an SQLWarning, null if there are no warnings
541     * @throws SQLException
542     *             if an error occurs accessing the database.
543     */
544    public SQLWarning getWarnings() throws SQLException;
545
546    /**
547     * Sets the SQL cursor name. This name is used by subsequent statement
548     * execute methods.
549     * <p>
550     * Cursor names must be unique within one Connection.
551     * <p>
552     * With the cursor name set, it can then be used in SQL positioned
553     * update or delete statements to determine the current row in a {@code
554     * ResultSet} generated from this statement. The positioned update or delete
555     * must be done with a different statement than this one.
556     *
557     * @param name
558     *            the Cursor name as a string,
559     * @throws SQLException
560     *             if an error occurs accessing the database.
561     */
562    public void setCursorName(String name) throws SQLException;
563
564    /**
565     * Sets Escape Processing mode.
566     * <p>
567     * If Escape Processing is on, the JDBC driver will do escape substitution
568     * on an SQL statement before sending it for execution. This does not apply
569     * to {@link PreparedStatement}s since they are processed when created,
570     * before this method can be called.
571     *
572     * @param enable
573     *            {@code true} to set escape processing mode <i>on</i>, {@code
574     *            false} to turn it <i>off</i>.
575     * @throws SQLException
576     *             if an error occurs accessing the database.
577     */
578    public void setEscapeProcessing(boolean enable) throws SQLException;
579
580    /**
581     * Sets the fetch direction - a hint to the JDBC driver about the direction
582     * of processing of rows in {@code ResultSet}s created by this statement.
583     * The default fetch direction is {@code FETCH_FORWARD}.
584     *
585     * @param direction
586     *            which fetch direction to use. This parameter should be one of
587     *            <ul>
588     *            <li>{@code ResultSet.FETCH_UNKNOWN}</li>
589     *            <li>{@code ResultSet.FETCH_FORWARD}</li>
590     *            <li>{@code ResultSet.FETCH_REVERSE}</li>
591     *            </ul>
592     * @throws SQLException
593     *             if there is an error while accessing the database or if the
594     *             fetch direction is unrecognized.
595     */
596    public void setFetchDirection(int direction) throws SQLException;
597
598    /**
599     * Sets the fetch size. This is a hint to the JDBC driver about how many
600     * rows should be fetched from the database when more are required by
601     * application processing.
602     *
603     * @param rows
604     *            the number of rows that should be fetched. {@code 0} tells the driver
605     *            to ignore the hint. Should be less than {@code getMaxRows} for
606     *            this statement. Should not be negative.
607     * @throws SQLException
608     *             if an error occurs accessing the database, or if the rows
609     *             parameter is out of range.
610     */
611    public void setFetchSize(int rows) throws SQLException;
612
613    /**
614     * Sets the maximum number of bytes for {@code ResultSet} columns that
615     * contain character or binary values. This applies to {@code BINARY},
616     * {@code VARBINARY}, {@code LONGVARBINARY}, {@code CHAR}, {@code VARCHAR},
617     * and {@code LONGVARCHAR} fields. Any data exceeding the maximum size is
618     * abandoned without announcement.
619     *
620     * @param max
621     *            the maximum field size in bytes. {@code 0} means "no limit".
622     * @throws SQLException
623     *             if an error occurs accessing the database or the {@code max}
624     *             value is &lt; {@code 0}.
625     */
626    public void setMaxFieldSize(int max) throws SQLException;
627
628    /**
629     * Sets the maximum number of rows that any {@code ResultSet} can contain.
630     * If the number of rows exceeds this value, the additional rows are
631     * silently discarded.
632     *
633     * @param max
634     *            the maximum number of rows. {@code 0} means "no limit".
635     * @throws SQLException
636     *             if an error occurs accessing the database or if max < {@code
637     *             0}.
638     */
639    public void setMaxRows(int max) throws SQLException;
640
641    /**
642     * Sets the timeout, in seconds, for queries - how long the driver will
643     * allow for completion of a statement execution. If the timeout is
644     * exceeded, the query will throw an {@code SQLException}.
645     *
646     * @param seconds
647     *            timeout in seconds. 0 means no timeout ("wait forever")
648     * @throws SQLException
649     *             if an error occurs accessing the database or if seconds <
650     *             {@code 0}.
651     */
652    public void setQueryTimeout(int seconds) throws SQLException;
653
654    /**
655     * Returns true if this statement has been closed, false otherwise.
656     */
657    public boolean isClosed() throws SQLException;
658
659    /**
660     * Hints whether this statement should be pooled. Defaults to false for {@code Statement},
661     * but true for {@code CallableStatement} and {@code PreparedStatement}. Pool manager
662     * implementations may or may not honor this hint.
663     */
664    public void setPoolable(boolean poolable) throws SQLException;
665
666    /**
667     * Returns true if this statement is poolable, false otherwise.
668     */
669    public boolean isPoolable() throws SQLException;
670}
671