![]() |
Quadcap Embeddable Database |
00001 package com.quadcap.jdbc; 00002 00003 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 import java.io.IOException; 00042 00043 import java.sql.SQLException; 00044 import java.sql.SQLWarning; 00045 00046 import antlr.RecognitionException; 00047 import antlr.TokenStreamException; 00048 00049 import com.quadcap.sql.Database; 00050 import com.quadcap.sql.Session; 00051 import com.quadcap.sql.SQLParser; 00052 import com.quadcap.sql.Stmt; 00053 00054 import com.quadcap.util.ConfigNumber; 00055 import com.quadcap.util.Debug; 00056 import com.quadcap.util.Util; 00057 00058 /** 00059 * This class implements the <code>java.sql.Statement</code> interface, which 00060 * provides facilities for executing SQL statements on a database 00061 * connection, as part of that connection's transaction. 00062 * 00063 * TODO: setMaxFieldSize 00064 * TODO: setQueryTimeout 00065 * TODO: JDBC3.0: return generated keys 00066 * 00067 * @author Stan Bailes 00068 */ 00069 public class Statement implements java.sql.Statement { 00070 /*{com.quadcap.qed.Trace-vars.xml-1054} 00071 * <config-var> 00072 * <config-name>qed.trace.Statement</config-name> 00073 * <config-dflt>0</config-dflt> 00074 * <config-desc> 00075 * <pre> 00076 * bit 0: statement lifecycle 00077 * bit 1: statement execution 00078 * bit 2: statement + result 00079 * bit 4: params in prepared statements 00080 * </pre> 00081 * </config-desc> 00082 * </config-var> 00083 */ 00084 static final ConfigNumber trace = 00085 ConfigNumber.find("qed.trace.Statement", "0"); 00086 00087 Connection conn; 00088 com.quadcap.sql.Connection qConn = null; 00089 Session session = null; 00090 ResultSet rs = null; 00091 int updateCount = -1; 00092 protected boolean escapeProcessing = true; 00093 int maxRows = -1; 00094 00095 /** 00096 * Create a new statement 00097 */ 00098 public Statement(Connection conn) throws SQLException, IOException { 00099 this.conn = conn; 00100 this.qConn = conn.getConnection(); 00101 this.session = qConn.createSession(); 00102 //#ifdef DEBUG 00103 if (trace.bit(0)) { 00104 Debug.println(toString() + " created"); 00105 } 00106 //#endif 00107 } 00108 00109 /** 00110 * Create a new Statement with the specified result set type and 00111 * concurrency. 00112 */ 00113 public Statement(Connection conn, int resultSetType, 00114 int resultSetConcurrency) 00115 throws SQLException, IOException 00116 { 00117 this(conn); 00118 this.resultSetType = resultSetType; 00119 this.resultSetConcurrency = resultSetConcurrency; 00120 } 00121 00122 /** 00123 * My short life is ended 00124 */ 00125 public void finalize() throws Throwable { 00126 try { 00127 close(); 00128 } catch (Throwable t) {} 00129 super.finalize(); 00130 } 00131 00132 /** 00133 * This QED release doesn't support batch statement execution. 00134 * 00135 * @exception SQLException "not implemented" 00136 */ 00137 public void addBatch(String sql) throws SQLException { 00138 throw new SQLException("not implemented", "0A000"); 00139 } 00140 00141 /** 00142 * QED does not support the <code>cancel()</code> feature. 00143 */ 00144 public void cancel() throws SQLException { 00145 } 00146 00147 /** 00148 * This QED release doesn't support batch statement execution. 00149 * 00150 * @exception SQLException "not implemented" 00151 */ 00152 public void clearBatch() throws SQLException { 00153 throw new SQLException("not implemented", "0A000"); 00154 } 00155 00156 /** 00157 * Clear any warnings associated with this <code>Statement</code> 00158 * object. Since this QED release doesn't generate 00159 * <code>SQLWarning</code>s, this function does nothing. 00160 */ 00161 public void clearWarnings() { 00162 } 00163 00164 /** 00165 * Close this statement object and free up any resources held by it. 00166 */ 00167 public void close() { 00168 //#ifdef DEBUG 00169 if (trace.bit(0)) { 00170 Debug.println(toString() + ".close()"); 00171 } 00172 //#endif 00173 if (session != null) { 00174 try { 00175 session.close(); 00176 } catch (SQLException e) { 00177 } catch (IOException e) { 00178 } finally { 00179 session = null; 00180 qConn = null; 00181 } 00182 } 00183 } 00184 00185 //#ifdef DEBUG 00186 public String toString() { 00187 return "Statement[" + session == null ? "" : session.toString() + "]"; 00188 } 00189 //#endif 00190 00191 /** 00192 * Execute the specified SQL statement, returning <code>true</code> 00193 * if the statement generates a <code>ResultSet</code> object. 00194 * 00195 * @param sql an SQL statement 00196 * @return true if execution of the statement results in the creation 00197 * of a <code>ResultSet</code> 00198 * @see #getResultSet() 00199 * @exception SQLException may be thrown 00200 */ 00201 public boolean execute(String sql) throws SQLException { 00202 //#ifdef DEBUG 00203 if (trace.bit(1)) { 00204 Debug.println(toString() + ".execute(" + sql + ")"); 00205 } 00206 //#endif 00207 if (this.qConn == null || this.qConn.isClosed()) { 00208 throw new SQLException("Connection closed"); 00209 } 00210 00211 if (this.rs != null) { 00212 this.rs.close(); 00213 this.rs = null; 00214 } 00215 this.updateCount = -1; 00216 00217 session.makeTransaction(); 00218 SQLParser p = new SQLParser(session, sql, escapeProcessing); 00219 String auth = qConn.getAuth(); 00220 //#ifdef DEBUG 00221 String res = ""; 00222 //#endif 00223 try { 00224 try { 00225 Stmt s = p.statement(); 00226 if (s == null) { 00227 throw new SQLException("Parse error", "42000"); 00228 } 00229 session.doStatement(s); 00230 this.rs = (ResultSet)session.getResultSet(this); 00231 if (rs != null) { 00232 //#ifdef DEBUG 00233 res = "true"; 00234 //#endif 00235 return true; 00236 } else { 00237 this.updateCount = session.getUpdateCount(); 00238 //#ifdef DEBUG 00239 res = String.valueOf(updateCount); 00240 //#endif 00241 return false; 00242 } 00243 } catch (IOException e) { 00244 //#ifdef DEBUG 00245 res = e.toString(); 00246 //#endif 00247 Debug.print(e); 00248 session.endStatement(true); 00249 throw new SQLException(e.toString(), "Q0012"); 00250 } catch (RecognitionException e) { 00251 //#ifdef DEBUG 00252 Debug.print(e); 00253 Debug.println("SQL: " + sql); 00254 res = e.toString(); 00255 //#endif 00256 session.endStatement(true); 00257 SQLException se = new SQLException("Statment: " + sql); 00258 SQLException s2 = new SQLException(e.toString(), "42000"); 00259 s2.setNextException(se); 00260 throw s2; 00261 } catch (TokenStreamException e) { 00262 //#ifdef DEBUG 00263 res = e.toString(); 00264 //#endif 00265 session.endStatement(true); 00266 SQLException se = new SQLException("Statment: " + sql); 00267 SQLException s2 = new SQLException(e.toString(), "42000"); 00268 s2.setNextException(se); 00269 throw s2; 00270 } catch (SQLException e) { 00271 //#ifdef DEBUG 00272 res = e.toString(); 00273 //#endif 00274 session.endStatement(true); 00275 throw e; 00276 } catch (Throwable e) { 00277 //#ifdef DEBUG 00278 res = e.toString(); 00279 Debug.println("Throwable: " + e); 00280 Debug.print(e); 00281 //#endif 00282 session.endStatement(true); 00283 throw new SQLException(e.toString(), "Q0013"); 00284 } 00285 } catch (IOException e) { 00286 Debug.print(e); 00287 throw new SQLException(e.toString(), "Q0014"); 00288 } finally { 00289 // XXX restore auth in case of createSchema 00290 // This is a hack. 'create schema' will temporarily set the 00291 // 'auth' to the schema name, and this is the first place where 00292 // we get a chance to restore the correct auth. 00293 // 00294 // This is made worse by the fact that names are resolved during 00295 // the parse phase, and could be made better if antlr parser 00296 // rules allowed you to specify a 'finally' handler. 00297 00298 // Also 'create schema' where the schema name is a parameter is 00299 // going to fail badly. 00300 session.getConnection().setAuth(auth, null); 00301 //#ifdef DEBUG 00302 if (trace.bit(2)) { 00303 Debug.println("Statement.execute(" + sql + ") = " + res); 00304 } 00305 //#endif 00306 } 00307 } 00308 00309 /** 00310 * This QED release doesn't support batch statement execution. 00311 * 00312 * @exception SQLException "not implemented" 00313 */ 00314 public int[] executeBatch() throws SQLException { 00315 throw new SQLException("not implemented", "0A000"); 00316 } 00317 00318 00319 /** 00320 * Execute the specified SQL query statement, returning the 00321 * <code>ResultSet</code> object containing the results of the 00322 * query. 00323 * 00324 * @param sql an SQL query statement 00325 * @return a <code>ResultSet</code> object containing the results of 00326 * the query 00327 * @exception SQLException may be thrown 00328 */ 00329 public java.sql.ResultSet executeQuery(String sql) throws SQLException { 00330 if (execute(sql)) { 00331 return this.rs; 00332 } else { 00333 return null; 00334 } 00335 } 00336 00337 /** 00338 * Execute the specified SQL update statement, returning the update 00339 * count, meaning the number of rows updated or inserted by this 00340 * statement. 00341 * 00342 * @param sql an SQL update statement 00343 * @return the update count 00344 * @exception SQLException may be thrown 00345 */ 00346 public int executeUpdate(String sql) throws SQLException { 00347 if (!execute(sql)) { 00348 return this.updateCount; 00349 } else { 00350 return 0; 00351 } 00352 } 00353 00354 /** 00355 * Return the <code>Connection</code> object used to create this 00356 * <code>Statement</code> object. 00357 * 00358 * @return this statement's connection. 00359 */ 00360 public java.sql.Connection getConnection() { 00361 return conn; 00362 } 00363 00364 /** 00365 * In QED, the fetch size is always 1. 00366 * 00367 * @return one 00368 */ 00369 public int getFetchSize() { 00370 return 1; 00371 } 00372 00373 /** 00374 * QED imposes no maximum field size. 00375 * 00376 * @return zero, meaning unlimited 00377 */ 00378 public int getMaxFieldSize() { 00379 return 0; 00380 } 00381 00382 /** 00383 * QED imposes no limit on the number of rows in a <code>ResultSet</code>. 00384 * 00385 * @return zero, meaning unlimited 00386 */ 00387 public int getMaxRows() { 00388 return 0; 00389 } 00390 00391 /** 00392 * QED only returns one <code>ResultSet</code> per statement, so 00393 * this function always returns <code>false</code> (after closing 00394 * the current <code>ResultSet</code> object for this 00395 * <code>Statement</code>. 00396 * 00397 * @return false 00398 * @exception SQLException may be thrown 00399 */ 00400 public boolean getMoreResults() throws SQLException { 00401 if (rs != null) rs.close(); 00402 this.updateCount = -1; 00403 return false; 00404 } 00405 00406 /** 00407 * QED doesn't support query timeouts, so this method always returns 00408 * zero. 00409 * 00410 * @return zero, meaning unlimited 00411 */ 00412 public int getQueryTimeout() { 00413 return 0; 00414 } 00415 00416 /** 00417 * Return the <code>ResultSet</code> generated by the last call to 00418 * <code>execute()</code>, unless that <code>ResultSet</code> has 00419 * been closed, or if there was no <code>ResultSet</code> generated 00420 * by the last call to <code>execute()</code>, in which case, return 00421 * <code>null</code>. 00422 * 00423 * @return the current <code>ResultSet</code> 00424 * 00425 */ 00426 public java.sql.ResultSet getResultSet() { 00427 return rs; 00428 } 00429 00430 /** 00431 * Return the update count for the last statement executed. If no 00432 * records were updated, inserted, or deleted, return -1. 00433 * 00434 * @return the update count for the last <code>execute()</code> 00435 * operation 00436 */ 00437 public int getUpdateCount() { 00438 return updateCount; 00439 } 00440 00441 /** 00442 * Since this QED release doesn't generate 00443 * <code>SQLWarning</code>s, this function always returns null. 00444 * 00445 * @return null 00446 */ 00447 public SQLWarning getWarnings() { 00448 return null; 00449 } 00450 00451 /** 00452 * This QED release doesn't support SQL named cursors 00453 * 00454 * @exception SQLException "not implemented" 00455 */ 00456 public void setCursorName(String name) throws SQLException { 00457 throw new SQLException("not implemented", "0A000"); 00458 } 00459 00460 /** 00461 * Enable or disable JDBC escape processing mode. 00462 * 00463 * @boolean enable <code>true</code> is the driver should perform 00464 * JDBC escape processing on statement execution. 00465 */ 00466 public void setEscapeProcessing(boolean enable) { 00467 escapeProcessing = enable; 00468 } 00469 00470 /** 00471 * Set the default fetch direction for <code>ResultSet</code> objects 00472 * generated by this <code>Statement</code> object. 00473 */ 00474 public void setFetchDirection(int dir) throws SQLException { 00475 } 00476 00477 /** 00478 * QED, being an embedded driver, fetches rows only when they are 00479 * needed, with no performance penalty. Thus, the fetch size is 00480 * always <code>one</code>, and this function has no effect. 00481 */ 00482 public void setFetchSize(int x) throws SQLException { 00483 } 00484 00485 /** 00486 * Not implemented in this release of QED 00487 * 00488 * @exception SQLException "not implemented" 00489 */ 00490 public void setMaxFieldSize(int x) throws SQLException { 00491 throw new SQLException("not implemented", "0A000"); 00492 } 00493 00494 /** 00495 * Set the maximum number of rows that will be returned by this 00496 * ResultSet 00497 */ 00498 public void setMaxRows(int x) throws SQLException { 00499 maxRows = x; 00500 } 00501 00502 /** 00503 * Not implemented in this release of QED 00504 * 00505 * @exception SQLException "not implemented" 00506 */ 00507 public void setQueryTimeout(int x) throws SQLException { 00508 throw new SQLException("not implemented", "0A000"); 00509 } 00510 00511 int resultSetType = ResultSet.TYPE_SCROLL_INSENSITIVE; 00512 int resultSetConcurrency = ResultSet.CONCUR_UPDATABLE; 00513 00514 /** 00515 * Return the default result set concurrency for <code>ResultSet</code> 00516 * objects generated by this <code>Statement</code> object. 00517 * 00518 * @return the default result set concurrency 00519 */ 00520 public int getResultSetConcurrency() { 00521 return resultSetConcurrency; 00522 } 00523 00524 /** 00525 * Return the default result set type for <code>ResultSet</code> 00526 * objects generated by this <code>Statement</code> object. 00527 * 00528 * @return the default result set type 00529 */ 00530 public int getResultSetType() { 00531 return resultSetType; 00532 } 00533 00534 /** 00535 * This release of QED only supports the fetch direction: 00536 * <code>ResultSet.FETCH_FORWARD</code> 00537 * 00538 * @return <code>ResultSet.FETCH_FORWARD</code> 00539 */ 00540 public int getFetchDirection() { 00541 return ResultSet.FETCH_FORWARD; 00542 } 00543 00544 // JDBC 3.0 ------------------------------------------------------- 00545 //#ifdef JDK14 00546 /** 00547 * Moves to this <code>Statement</code> object's next result, deals with 00548 * any current <code>ResultSet</code> object(s) according to the 00549 * instructions specified by the given flag, and returns 00550 * <code>true</code> if the next result is a <code>ResultSet</code> object. 00551 * 00552 * <P>There are no more results when the following is true: 00553 * <PRE> 00554 * <code>(!getMoreResults() && (getUpdateCount() == -1)</code> 00555 * </PRE> 00556 * 00557 * @param current one of the following <code>Statement</code> 00558 * constants indicating what should happen to current 00559 * <code>ResultSet</code> objects obtained using the method 00560 * <code>getResultSet</code: 00561 * <code>CLOSE_CURRENT_RESULT</code>, 00562 * <code>KEEP_CURRENT_RESULT</code>, or 00563 * <code>CLOSE_ALL_RESULTS</code> 00564 * @return <code>true</code> if the next result is a <code>ResultSet</code> 00565 * object; <code>false</code> if it is an update count or there are no 00566 * more results 00567 * @exception SQLException if a database access error occurs 00568 * @since 1.4 00569 * @see #execute 00570 */ 00571 public boolean getMoreResults(int current) throws SQLException { 00572 if (current == KEEP_CURRENT_RESULT) { 00573 throw new SQLException("JDBC 3.0 feature KEEP_CURRENT_RESULT " + 00574 "not implemented"); 00575 } 00576 return getMoreResults(); 00577 } 00578 00579 /** 00580 * Retrieves any auto-generated keys created as a result of executing this 00581 * <code>Statement</code> object. If this <code>Statement</code> object 00582 * did not generate any keys, an empty <code>ResultSet</code> 00583 * object is returned. 00584 * 00585 * @return a <code>ResultSet</code> object containing the auto-generated 00586 * key(s) generated by the execution of this 00587 * <code>Statement</code> object 00588 * @exception SQLException if a database access error occurs 00589 * @since 1.4 00590 */ 00591 public java.sql.ResultSet getGeneratedKeys() throws SQLException { 00592 throw new SQLException("JDBC3.0 feature not implemented"); 00593 } 00594 00595 /** 00596 * Executes the given SQL statement and signals the driver with the 00597 * given flag about whether the 00598 * auto-generated keys produced by this <code>Statement</code> object 00599 * should be made available for retrieval. 00600 * 00601 * @param sql must be an SQL <code>INSERT</code>, <code>UPDATE</code> or 00602 * <code>DELETE</code> statement or an SQL statement that 00603 * returns nothing 00604 * @param autoGeneratedKeys a flag indicating whether auto-generated keys 00605 * should be made available for retrieval; 00606 * one of the following constants: 00607 * <code>Statement.RETURN_GENERATED_KEYS</code> 00608 * <code>Statement.NO_GENERATED_KEYS</code> 00609 * @return either the row count for <code>INSERT</code>, 00610 * <code>UPDATE</code> 00611 * or <code>DELETE</code> statements, or <code>0</code> for SQL 00612 * statements that return nothing 00613 * @exception SQLException if a database access error occurs, the given 00614 * SQL statement returns a <code>ResultSet</code> object, or 00615 * the given constant is not one of those allowed 00616 * @since 1.4 00617 */ 00618 public int executeUpdate(String sql, int autoGeneratedKeys) 00619 throws SQLException 00620 { 00621 if (autoGeneratedKeys == RETURN_GENERATED_KEYS) { 00622 throw new SQLException("JDBC3.0 feature not implemented"); 00623 } 00624 return executeUpdate(sql); 00625 } 00626 00627 /** 00628 * Executes the given SQL statement and signals the driver that the 00629 * auto-generated keys indicated in the given array should be made 00630 * available for retrieval. The driver will ignore the array if the 00631 * SQL statement is not an <code>INSERT</code> statement. 00632 * 00633 * @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or 00634 * <code>DELETE</code> statement or an SQL statement that returns 00635 * nothing, such as an SQL DDL statement 00636 * @param columnIndexes an array of column indexes indicating the columns 00637 * that should be returned from the inserted row 00638 * @return either the row count for <code>INSERT</code>, 00639 * <code>UPDATE</code>, 00640 * or <code>DELETE</code> statements, or 0 for SQL statements 00641 * that return nothing 00642 * @exception SQLException if a database access error occurs or the SQL 00643 * statement returns a <code>ResultSet</code> object 00644 * @since 1.4 00645 */ 00646 public int executeUpdate(String sql, int columnIndexes[]) 00647 throws SQLException 00648 { 00649 return executeUpdate(sql); 00650 } 00651 00652 /** 00653 * Executes the given SQL statement and signals the driver that the 00654 * auto-generated keys indicated in the given array should be made available 00655 * for retrieval. The driver will ignore the array if the SQL statement 00656 * is not an <code>INSERT</code> statement. 00657 * 00658 * @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or 00659 * <code>DELETE</code> statement or an SQL statement that returns nothing 00660 * @param columnNames an array of the names of the columns that should be 00661 * returned from the inserted row 00662 * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>, 00663 * or <code>DELETE</code> statements, or 0 for SQL statements 00664 * that return nothing 00665 * @exception SQLException if a database access error occurs 00666 * 00667 * @since 1.4 00668 */ 00669 public int executeUpdate(String sql, String columnNames[]) 00670 throws SQLException 00671 { 00672 return executeUpdate(sql); 00673 } 00674 00675 /** 00676 * Executes the given SQL statement, which may return multiple results, 00677 * and signals the driver that any 00678 * auto-generated keys should be made available 00679 * for retrieval. The driver will ignore this signal if the SQL statement 00680 * is not an <code>INSERT</code> statement. 00681 * <P> 00682 * In some (uncommon) situations, a single SQL statement may return 00683 * multiple result sets and/or update counts. Normally you can ignore 00684 * this unless you are (1) executing a stored procedure that you know may 00685 * return multiple results or (2) you are dynamically executing an 00686 * unknown SQL string. 00687 * <P> 00688 * The <code>execute</code> method executes an SQL statement and indicates the 00689 * form of the first result. You must then use the methods 00690 * <code>getResultSet</code> or <code>getUpdateCount</code> 00691 * to retrieve the result, and <code>getMoreResults</code> to 00692 * move to any subsequent result(s). 00693 * 00694 * @param sql any SQL statement 00695 * @param autoGeneratedKeys a constant indicating whether auto-generated 00696 * keys should be made available for retrieval using the method 00697 * <code>getGeneratedKeys</code>; one of the following constants: 00698 * <code>Statement.RETURN_GENERATED_KEYS</code> or 00699 * <code>Statement.NO_GENERATED_KEYS</code> 00700 * @return <code>true</code> if the first result is a <code>ResultSet</code> 00701 * object; <code>false</code> if it is an update count or there are 00702 * no results 00703 * @exception SQLException if a database access error occurs 00704 * @see #getResultSet 00705 * @see #getUpdateCount 00706 * @see #getMoreResults 00707 * @see #getGeneratedKeys 00708 * 00709 * @since 1.4 00710 */ 00711 public boolean execute(String sql, int autoGeneratedKeys) 00712 throws SQLException 00713 { 00714 return execute(sql); 00715 } 00716 00717 /** 00718 * Executes the given SQL statement, which may return multiple results, 00719 * and signals the driver that the 00720 * auto-generated keys indicated in the given array should be made available 00721 * for retrieval. This array contains the indexes of the columns in the 00722 * target table that contain the auto-generated keys that should be made 00723 * available. The driver will ignore the array if the given SQL statement 00724 * is not an <code>INSERT</code> statement. 00725 * <P> 00726 * Under some (uncommon) situations, a single SQL statement may return 00727 * multiple result sets and/or update counts. Normally you can ignore 00728 * this unless you are (1) executing a stored procedure that you know may 00729 * return multiple results or (2) you are dynamically executing an 00730 * unknown SQL string. 00731 * <P> 00732 * The <code>execute</code> method executes an SQL statement and indicates the 00733 * form of the first result. You must then use the methods 00734 * <code>getResultSet</code> or <code>getUpdateCount</code> 00735 * to retrieve the result, and <code>getMoreResults</code> to 00736 * move to any subsequent result(s). 00737 * 00738 * @param sql any SQL statement 00739 * @param columnIndexes an array of the indexes of the columns in the 00740 * inserted row that should be made available for retrieval by a 00741 * call to the method <code>getGeneratedKeys</code> 00742 * @return <code>true</code> if the first result is a <code>ResultSet</code> 00743 * object; <code>false</code> if it is an update count or there 00744 * are no results 00745 * @exception SQLException if a database access error occurs 00746 * @see #getResultSet 00747 * @see #getUpdateCount 00748 * @see #getMoreResults 00749 * 00750 * @since 1.4 00751 */ 00752 public boolean execute(String sql, int columnIndexes[]) 00753 throws SQLException 00754 { 00755 return execute(sql); 00756 } 00757 00758 /** 00759 * Executes the given SQL statement, which may return multiple results, 00760 * and signals the driver that the 00761 * auto-generated keys indicated in the given array should be made available 00762 * for retrieval. This array contains the names of the columns in the 00763 * target table that contain the auto-generated keys that should be made 00764 * available. The driver will ignore the array if the given SQL statement 00765 * is not an <code>INSERT</code> statement. 00766 * <P> 00767 * In some (uncommon) situations, a single SQL statement may return 00768 * multiple result sets and/or update counts. Normally you can ignore 00769 * this unless you are (1) executing a stored procedure that you know may 00770 * return multiple results or (2) you are dynamically executing an 00771 * unknown SQL string. 00772 * <P> 00773 * The <code>execute</code> method executes an SQL statement and indicates the 00774 * form of the first result. You must then use the methods 00775 * <code>getResultSet</code> or <code>getUpdateCount</code> 00776 * to retrieve the result, and <code>getMoreResults</code> to 00777 * move to any subsequent result(s). 00778 * 00779 * @param sql any SQL statement 00780 * @param columnNames an array of the names of the columns in the inserted 00781 * row that should be made available for retrieval by a call to the 00782 * method <code>getGeneratedKeys</code> 00783 * @return <code>true</code> if the next result is a <code>ResultSet</code> 00784 * object; <code>false</code> if it is an update count or there 00785 * are no more results 00786 * @exception SQLException if a database access error occurs 00787 * @see #getResultSet 00788 * @see #getUpdateCount 00789 * @see #getMoreResults 00790 * @see #getGeneratedKeys 00791 * 00792 * @since 1.4 00793 */ 00794 public boolean execute(String sql, String columnNames[]) 00795 throws SQLException 00796 { 00797 return execute(sql); 00798 } 00799 00800 /** 00801 * Retrieves the result set holdability for <code>ResultSet</code> objects 00802 * generated by this <code>Statement</code> object. 00803 * 00804 * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or 00805 * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code> 00806 * @exception SQLException if a database access error occurs 00807 * 00808 * @since 1.4 00809 */ 00810 public int getResultSetHoldability() throws SQLException { 00811 return ResultSet.CLOSE_CURSORS_AT_COMMIT; 00812 } 00813 //#endif 00814 00815 }