00001 /** 00002 * C-JDBC: Clustered JDBC. 00003 * Copyright (C) 2002-2005 French National Institute For Research In Computer 00004 * Science And Control (INRIA). 00005 * Contact: c-jdbc@objectweb.org 00006 * 00007 * This library is free software; you can redistribute it and/or modify it 00008 * under the terms of the GNU Lesser General Public License as published by the 00009 * Free Software Foundation; either version 2.1 of the License, or any later 00010 * version. 00011 * 00012 * This library is distributed in the hope that it will be useful, but WITHOUT 00013 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 00015 * for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public License 00018 * along with this library; if not, write to the Free Software Foundation, 00019 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00020 * 00021 * Initial developer(s): Emmanuel Cecchet. 00022 * Contributor(s): Vadim Kassin, Jean-Bernard van Zuylen. 00023 */ 00024 00025 package org.objectweb.cjdbc.driver; 00026 00027 import java.sql.BatchUpdateException; 00028 import java.sql.ResultSet; 00029 import java.sql.SQLException; 00030 import java.sql.SQLWarning; 00031 import java.util.Vector; 00032 00033 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest; 00034 import org.objectweb.cjdbc.common.sql.AlterRequest; 00035 import org.objectweb.cjdbc.common.sql.CreateRequest; 00036 import org.objectweb.cjdbc.common.sql.DeleteRequest; 00037 import org.objectweb.cjdbc.common.sql.DropRequest; 00038 import org.objectweb.cjdbc.common.sql.InsertRequest; 00039 import org.objectweb.cjdbc.common.sql.NotImplementedException; 00040 import org.objectweb.cjdbc.common.sql.SelectRequest; 00041 import org.objectweb.cjdbc.common.sql.StoredProcedure; 00042 import org.objectweb.cjdbc.common.sql.UpdateRequest; 00043 00044 /** 00045 * A <code>Statement</code> object is used for executing a static SQL 00046 * statement and obtaining the results produced by it. 00047 * <p> 00048 * Only one <code>ResultSet</code> per <code>Statement</code> can be open at 00049 * any point in time. Therefore, if the reading of one <code>ResultSet</code> 00050 * is interleaved with the reading of another, each must have been generated by 00051 * different <code>Statements</code>. All <code>Statements</code> execute 00052 * methods implicitly close a statement's current <code>ResultSet</code> if an 00053 * open one exists. 00054 * 00055 * @see java.sql.Statement 00056 * @see DriverResultSet 00057 * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a> 00058 * @author <a href="mailto:vadim@kase.kz">Vadim Kassin </a> 00059 * @author <a href="mailto:jbvanzuylen@transwide.com">Jean-Bernard van Zuylen </a> 00060 * @version 1.0 00061 */ 00062 public class Statement implements java.sql.Statement 00063 { 00064 /** The connection that created us */ 00065 protected Connection connection = null; 00066 00067 /** Vector for batch commands */ 00068 private Vector batch = null; 00069 00070 /** The warnings chain */ 00071 private SQLWarning warnings = null; 00072 00073 /** The current result for a read request */ 00074 protected ResultSet result = null; 00075 00076 /** The update count for a write request */ 00077 protected int updateCount = -1; 00078 00079 /** Query timeout in seconds (0 means no timeout) */ 00080 private int timeout = 0; 00081 00082 /** Default ResultSet fetch size */ 00083 private int fetchSize = 0; 00084 /** Cursor name used jointly with fetch size */ 00085 private String cursorName; 00086 00087 /** Type of the ResultSet defaults to TYPE_FORWARD_ONLY */ 00088 private int resultSetType = ResultSet.TYPE_FORWARD_ONLY; 00089 00090 /** ResultSet Concurrency defaults to CONCUR_READ_ONLY */ 00091 private int resultSetConcurrency = ResultSet.CONCUR_READ_ONLY; 00092 00093 /** Maximum field size (unused) */ 00094 private int maxFieldSize = 0; 00095 00096 /** Maximum number of rows (unused) */ 00097 private int maxRows = 0; 00098 00099 /** 00100 * Should the driver to escape processing before sending to the DB? 00101 */ 00102 protected boolean escapeProcessing = true; 00103 00104 /** Auto generated keys */ 00105 protected ResultSet generatedKeys = null; 00106 protected int generatedKeysFlag = java.sql.Statement.NO_GENERATED_KEYS; 00107 00108 /** 00109 * Creates a new <code>Statement</code> instance. 00110 * 00111 * @param c the <code>Connection</code> that created us 00112 */ 00113 public Statement(Connection c) 00114 { 00115 connection = c; 00116 } 00117 00118 /** 00119 * Adds sql to the current list of commands. 00120 * 00121 * @param sql an SQL statement that returns an update count (INSERT or UPDATE) 00122 * @exception SQLException if an error occurs 00123 */ 00124 public void addBatch(String sql) throws SQLException 00125 { 00126 if (batch == null) 00127 batch = new Vector(); 00128 batch.addElement(sql.trim()); 00129 } 00130 00131 /** 00132 * Could be use by one thread to cancel a statement that is being executed by 00133 * another thread. We don't support that for instance. 00134 * 00135 * @exception SQLException if an error occurs 00136 */ 00137 public void cancel() throws SQLException 00138 { 00139 throw new NotImplementedException("cancel()"); 00140 } 00141 00142 /** 00143 * Empties the current list of commands. 00144 * 00145 * @exception SQLException if an error occurs 00146 */ 00147 public void clearBatch() throws SQLException 00148 { 00149 if (batch != null) 00150 batch.removeAllElements(); 00151 } 00152 00153 /** 00154 * After this call, <code>getWarnings</code> returns <code>null</code> 00155 * until a new warning is reported for this <code>Statement</code>. 00156 * 00157 * @exception SQLException if a database access error occurs (why?) 00158 */ 00159 public void clearWarnings() throws SQLException 00160 { 00161 warnings = null; 00162 } 00163 00164 /** 00165 * Execute a batch of commands 00166 * 00167 * @return an array containing update count that corresponding to the commands 00168 * that executed successfully 00169 * @exception SQLException if an error occurs 00170 */ 00171 public int[] executeBatch() throws SQLException 00172 { 00173 if (batch == null || batch.isEmpty()) 00174 return new int[0]; 00175 00176 int size = batch.size(); 00177 int[] result = new int[size]; 00178 int i = 0; 00179 00180 try 00181 { 00182 for (i = 0; i < size; i++) 00183 result[i] = this.executeUpdate((String) batch.elementAt(i)); 00184 return result; 00185 } 00186 catch (SQLException e) 00187 { 00188 String message = "Batch failed for request " + i + ": " 00189 + batch.elementAt(i) + " (" + e + ")"; 00190 00191 int[] updateCounts = new int[i]; 00192 System.arraycopy(result, 0, updateCounts, 0, i); 00193 00194 throw new BatchUpdateException(message, updateCounts); 00195 } 00196 finally 00197 { 00198 batch.removeAllElements(); 00199 } 00200 } 00201 00202 /** 00203 * In many cases, it is desirable to immediately release a Statement's 00204 * database and JDBC resources instead of waiting for this to happen when it 00205 * is automatically closed. The close method provides this immediate release. 00206 * <p> 00207 * <B>Note: </B> A Statement is automatically closed when it is garbage 00208 * collected. When a Statement is closed, its current ResultSet, if one 00209 * exists, is also closed. 00210 * 00211 * @exception SQLException if a database access error occurs (why?) 00212 */ 00213 public void close() throws SQLException 00214 { 00215 // Force the ResultSet to close 00216 if (result != null) 00217 result.close(); 00218 00219 // Disasociate it from us (For Garbage Collection) 00220 result = null; 00221 connection = null; 00222 } 00223 00224 /** 00225 * Execute a SQL statement that may return multiple results. 00226 * 00227 * @param sql any SQL statement 00228 * @return true if the result is a ResultSet or false if it is an integer 00229 * @exception SQLException if an error occurs 00230 */ 00231 public boolean execute(String sql) throws SQLException 00232 { 00233 int start = 0; 00234 try 00235 { 00236 // Ignore any leading parenthesis 00237 while (sql.charAt(start) == '(') 00238 start++; 00239 } 00240 catch (IndexOutOfBoundsException e) 00241 { 00242 // Probably a buggy request, let it go through and let thefollowing code 00243 // to report an accurate error if any. 00244 start = 0; 00245 } 00246 00247 if (sql.regionMatches(true, start, "select", 0, 6) 00248 || (sql.regionMatches(true, start, "{call", 0, 5))) 00249 { 00250 result = executeQuery(sql); 00251 return true; 00252 } 00253 else 00254 { 00255 updateCount = executeUpdate(sql); 00256 return false; 00257 } 00258 } 00259 00260 /** 00261 * Execute a SQL statement that returns a single ResultSet 00262 * 00263 * @param sql typically a static SQL <code>SELECT</code> statement 00264 * @return a ResulSet that contains the data produced by the query 00265 * @exception SQLException if a database access error occurs 00266 */ 00267 public java.sql.ResultSet executeQuery(String sql) throws SQLException 00268 { 00269 return executeQuery(null, sql.trim()); 00270 } 00271 00272 /** 00273 * Execute a SQL statement that returns a single ResultSet 00274 * 00275 * @param sqlSkeleton the SQL request squeleton or null 00276 * @param sqlQuery typically a static SQL <code>SELECT</code> statement that 00277 * is already trimed 00278 * @return a ResulSet that contains the data produced by the query 00279 * @exception SQLException if a database access error occurs 00280 */ 00281 protected java.sql.ResultSet executeQuery(String sqlSkeleton, String sqlQuery) 00282 throws SQLException 00283 { 00284 updateCount = -1; // invalidate the last write result 00285 if (result != null) 00286 { // Discard the previous result 00287 result.close(); 00288 result = null; 00289 } 00290 00291 if (sqlQuery.regionMatches(true, 0, "{call", 0, 5)) 00292 { 00293 StoredProcedure proc = new StoredProcedure(sqlQuery, escapeProcessing, 00294 timeout, Connection.LINE_SEPARATOR); 00295 if (connection.needSqlSkeleton || !connection.isDriverProcessed()) 00296 proc.setSqlSkeleton(sqlSkeleton); 00297 proc.setMaxRows(maxRows); 00298 result = connection.execReadStoredProcedure(proc); 00299 } 00300 else 00301 { 00302 SelectRequest request = new SelectRequest(sqlQuery, escapeProcessing, 00303 timeout, Connection.LINE_SEPARATOR); 00304 if (connection.needSqlSkeleton || !connection.isDriverProcessed()) 00305 request.setSqlSkeleton(sqlSkeleton); 00306 request.setMaxRows(maxRows); 00307 request.setFetchSize(fetchSize); 00308 request.setCursorName(cursorName); 00309 result = connection.execReadRequest(request); 00310 } 00311 00312 if (result instanceof DriverResultSet) 00313 ((DriverResultSet) result).setStatement(this); 00314 return result; 00315 } 00316 00317 /** 00318 * Execute a SQL INSERT, UPDATE or DELETE statement. In addition SQL 00319 * statements that return nothing such as SQL DDL statements can be executed 00320 * 00321 * @param sql a SQL statement 00322 * @return either a row count, or 0 for SQL commands 00323 * @exception SQLException if a database access error occurs 00324 */ 00325 public int executeUpdate(String sql) throws SQLException 00326 { 00327 return executeUpdateWithSkeleton(null, sql.trim()); 00328 } 00329 00330 /** 00331 * Execute a SQL INSERT, UPDATE or DELETE statement. In addition SQL 00332 * statements that return nothing such as SQL DDL statements can be executed 00333 * 00334 * @param sqlSkeleton the SQL request squeleton or null 00335 * @param sqlQuery a static SQL statement that is already trimed 00336 * @return either a row count, or 0 for SQL commands 00337 * @exception SQLException if a database access error occurs 00338 */ 00339 protected int executeUpdateWithSkeleton(String sqlSkeleton, String sqlQuery) 00340 throws SQLException 00341 { 00342 if (result != null) 00343 { // Discard the previous result 00344 result.close(); 00345 result = null; 00346 } 00347 00348 // Check that the command starts with 00349 // insert/update/delete/create/drop/{call 00350 String lower = sqlQuery.substring(0, 00351 6 < sqlQuery.length() ? 6 : sqlQuery.length()).toLowerCase(); 00352 AbstractWriteRequest request; 00353 if (lower.equals("insert")) 00354 request = new InsertRequest(sqlQuery, escapeProcessing, timeout, 00355 Connection.LINE_SEPARATOR); 00356 else if (lower.equals("update")) 00357 request = new UpdateRequest(sqlQuery, escapeProcessing, timeout, 00358 Connection.LINE_SEPARATOR); 00359 else if (lower.equals("delete")) 00360 request = new DeleteRequest(sqlQuery, escapeProcessing, timeout, 00361 Connection.LINE_SEPARATOR); 00362 else if (lower.startsWith("create")) 00363 request = new CreateRequest(sqlQuery, escapeProcessing, timeout, 00364 Connection.LINE_SEPARATOR); 00365 else if (lower.startsWith("drop")) 00366 request = new DropRequest(sqlQuery, escapeProcessing, timeout, 00367 Connection.LINE_SEPARATOR); 00368 else if (lower.startsWith("alter")) 00369 request = new AlterRequest(sqlQuery, escapeProcessing, timeout, 00370 Connection.LINE_SEPARATOR); 00371 else if (lower.startsWith("{call")) 00372 { // Call stored procedure and return 00373 StoredProcedure proc = new StoredProcedure(sqlQuery, escapeProcessing, 00374 timeout, Connection.LINE_SEPARATOR); 00375 if (connection.needSqlSkeleton || !connection.isDriverProcessed()) 00376 proc.setSqlSkeleton(sqlSkeleton); 00377 updateCount = connection.execWriteStoredProcedure(proc); 00378 return updateCount; 00379 } 00380 else if (lower.startsWith("}call")) 00381 { // Call stored procedure and return. This hack is used to allow someone to 00382 // use execute() to call a write stored procedure. 00383 StoredProcedure proc = new StoredProcedure("{" + sqlQuery.substring(1), 00384 escapeProcessing, timeout, Connection.LINE_SEPARATOR); 00385 if (connection.needSqlSkeleton || !connection.isDriverProcessed()) 00386 proc.setSqlSkeleton(sqlSkeleton); 00387 updateCount = connection.execWriteStoredProcedure(proc); 00388 return updateCount; 00389 } 00390 else 00391 throw new SQLException( 00392 "executeUpdate only accepts statements starting with insert/update/delete/create/drop/{call (" 00393 + sqlQuery + ")"); 00394 00395 if (connection.needSqlSkeleton || !connection.isDriverProcessed()) 00396 request.setSqlSkeleton(sqlSkeleton); 00397 00398 if (generatedKeysFlag == Statement.RETURN_GENERATED_KEYS) 00399 { // Get the auto generated key back 00400 generatedKeys = connection.execWriteRequestWithKeys(request); 00401 00402 /* 00403 * Usually it is one autoincrement field and one generated key but if it 00404 * is not acceptable - better way to make another function for return 00405 * count of updates Or leave execWriteRequestWithKeys to return count and 00406 * add function for return ResultSet 00407 */ 00408 return 1; 00409 } 00410 else 00411 { // No generated keys 00412 updateCount = connection.execWriteRequest(request); 00413 return updateCount; 00414 } 00415 } 00416 00417 /** 00418 * Retrieve the connection that created this Statement object 00419 * 00420 * @return a <code>java.sql.Connection</code> object 00421 * @exception SQLException never 00422 */ 00423 public java.sql.Connection getConnection() throws SQLException 00424 { 00425 return connection; 00426 } 00427 00428 /** 00429 * Not supported yet. 00430 * 00431 * @return nothing 00432 * @exception SQLException not supported 00433 */ 00434 public int getFetchDirection() throws SQLException 00435 { 00436 throw new NotImplementedException("getFetchDirection()"); 00437 } 00438 00439 /** 00440 * @see java.sql.Statement#getFetchSize() 00441 */ 00442 public int getFetchSize() throws SQLException 00443 { 00444 return fetchSize; 00445 } 00446 00447 /** 00448 * The maxFieldSize limit (in bytes) is the maximum amount of data returned 00449 * for any column value; it only applies to <code>BINARY</code>, 00450 * <code>VARBINARY</code>,<code>LONGVARBINARY</code>,<code>CHAR</code>, 00451 * <code>VARCHAR</code> and <code>LONGVARCHAR</code> columns. If the limit 00452 * is exceeded, the excess data is silently discarded. 00453 * <p> 00454 * <b>Note: </b> We don't do anything with this value yet. 00455 * 00456 * @return the current max column size limit; zero means unlimited 00457 * @exception SQLException if a database access error occurs 00458 */ 00459 public int getMaxFieldSize() throws SQLException 00460 { 00461 return maxFieldSize; 00462 } 00463 00464 /** 00465 * The maxRows limit is set to limit the number of rows that any 00466 * <code>ResultSet</code> can contain. If the limit is exceeded, the excess 00467 * rows are silently dropped. 00468 * 00469 * @return the current maximum row limit; zero means unlimited 00470 * @exception SQLException if a database access error occurs 00471 */ 00472 public int getMaxRows() throws SQLException 00473 { 00474 return maxRows; 00475 } 00476 00477 /** 00478 * Multiple results are not suppoted so this method always return false and 00479 * reset the update count to -1. Any open ResultSet is implicitly closed. 00480 * 00481 * @return false 00482 * @exception SQLException if an error occurs 00483 */ 00484 public boolean getMoreResults() throws SQLException 00485 { 00486 if (result != null) 00487 result.close(); 00488 updateCount = -1; 00489 return false; 00490 } 00491 00492 /** 00493 * The queryTimeout limit is the number of seconds the driver will wait for a 00494 * Statement to execute. If the limit is exceeded, a <code>SQLException</code> 00495 * is thrown. 00496 * 00497 * @return the current query timeout limit in seconds; 0 = unlimited 00498 * @exception SQLException if a database access error occurs 00499 */ 00500 public int getQueryTimeout() throws SQLException 00501 { 00502 return timeout; 00503 } 00504 00505 /** 00506 * Returns the current result as a <code>ResultSet</code>. 00507 * 00508 * @return the current result set; null if there are no more 00509 * @exception SQLException never 00510 */ 00511 public java.sql.ResultSet getResultSet() throws SQLException 00512 { 00513 return result; 00514 } 00515 00516 /** 00517 * Retrieve the concurrency mode for the <code>ResultSet</code>. 00518 * 00519 * @return <code>CONCUR_READ_ONLY</code> or 00520 * <code>CONCUR_UPDATABLE</code> 00521 * @exception SQLException never 00522 */ 00523 public int getResultSetConcurrency() throws SQLException 00524 { 00525 return resultSetConcurrency; 00526 } 00527 00528 /** 00529 * Retrieve the type of the generated <code>ResultSet</code>. 00530 * 00531 * @return one of <code>TYPE_FORWARD_ONLY</code> or 00532 * <code>TYPE_SCROLL_INSENSITIVE</code> 00533 * @exception SQLException never 00534 */ 00535 public int getResultSetType() throws SQLException 00536 { 00537 return resultSetType; 00538 } 00539 00540 /** 00541 * Returns the current result as an update count, if the result is a 00542 * <code>ResultSet</code> or there are no more results, -1 is returned. It 00543 * should only be called once per result. 00544 * 00545 * @return the current result as an update count. 00546 * @exception SQLException if a database access error occurs 00547 */ 00548 public int getUpdateCount() throws SQLException 00549 { 00550 return updateCount; 00551 } 00552 00553 /** 00554 * The first warning reported by calls on this Statement is returned. A 00555 * Statement's execute methods clear its SQLWarning chain. Subsequent 00556 * <code>Statement</code> warnings will be chained to this SQLWarning. 00557 * <p> 00558 * The Warning chain is automatically cleared each time a statement is 00559 * (re)executed. 00560 * <p> 00561 * <B>Note: </B> if you are processing a <code>ResultSet</code> then any 00562 * warnings associated with <code>ResultSet</code> reads will be chained on 00563 * the <code>ResultSet</code> object. 00564 * 00565 * @return the first SQLWarning on null 00566 * @exception SQLException if a database access error occurs 00567 */ 00568 public SQLWarning getWarnings() throws SQLException 00569 { 00570 return warnings; 00571 } 00572 00573 /** 00574 * Defines the SQL cursor name that will be used by subsequent execute 00575 * methods. This name can then be used in SQL positioned update/delete 00576 * statements to identify the current row in the ResultSet generated by this 00577 * statement. If a database doesn't support positioned update/delete, this 00578 * method is a no-op. 00579 * <p> 00580 * 00581 * @param name the new cursor name 00582 * @exception SQLException not supported 00583 */ 00584 public void setCursorName(String name) throws SQLException 00585 { 00586 cursorName = name; 00587 } 00588 00589 /** 00590 * If escape scanning is on (the default), the driver will do escape 00591 * substitution before sending the SQL to the database. 00592 * 00593 * @param enable true to enable; false to disable 00594 * @exception SQLException if a database access error occurs 00595 */ 00596 public void setEscapeProcessing(boolean enable) throws SQLException 00597 { 00598 escapeProcessing = enable; 00599 } 00600 00601 /** 00602 * This hint is silently ignored and assumes FETCH_FORWARD which is the way 00603 * C-JDBC has been optimized for. 00604 * 00605 * @param direction ignored 00606 * @exception SQLException not supported 00607 */ 00608 public void setFetchDirection(int direction) throws SQLException 00609 { 00610 } 00611 00612 /** 00613 * Set the default fetch size for the produced ResultSet. 00614 * 00615 * @param rows ignored 00616 * @exception SQLException not supported 00617 */ 00618 public void setFetchSize(int rows) throws SQLException 00619 { 00620 fetchSize = rows; 00621 } 00622 00623 /** 00624 * Sets the <code>maxFieldSize</code>. 00625 * 00626 * @param max the new max column size limit; 0 means unlimited 00627 * @exception SQLException if a database access error occurs 00628 */ 00629 public void setMaxFieldSize(int max) throws SQLException 00630 { 00631 maxFieldSize = max; 00632 } 00633 00634 /** 00635 * Sets the maximum number of rows. 00636 * 00637 * @param max the new max rows limit; 0 means unlimited 00638 * @exception SQLException if a database access error occurs 00639 */ 00640 public void setMaxRows(int max) throws SQLException 00641 { 00642 maxRows = max; 00643 } 00644 00645 /** 00646 * Sets the queryTimeout limit. 00647 * 00648 * @param seconds the new query timeout limit in seconds (0 means no timeout) 00649 * @exception SQLException if a database access error occurs 00650 */ 00651 public void setQueryTimeout(int seconds) throws SQLException 00652 { 00653 timeout = seconds; 00654 } 00655 00656 /** 00657 * @param value an <code>int</code> value 00658 * @exception SQLException if an error occurs 00659 */ 00660 public void setResultSetConcurrency(int value) throws SQLException 00661 { 00662 switch (value) 00663 { 00664 case ResultSet.CONCUR_READ_ONLY: 00665 case ResultSet.CONCUR_UPDATABLE: 00666 resultSetConcurrency = value; 00667 break; 00668 default: 00669 throw new SQLException("Invalid ResultSet " + 00670 "concurrency mode: " + value); 00671 } 00672 } 00673 00674 /** 00675 * @param value an <code>int</code> value 00676 * @exception SQLException if an error occurs 00677 */ 00678 public void setResultSetType(int value) throws SQLException 00679 { 00680 switch (value) 00681 { 00682 case ResultSet.TYPE_FORWARD_ONLY: 00683 case ResultSet.TYPE_SCROLL_INSENSITIVE: 00684 resultSetType = value; 00685 break; 00686 case ResultSet.TYPE_SCROLL_SENSITIVE: 00687 throw new SQLException( 00688 "TYPE_SCROLL_SENSITIVE is not a supported ResultSet type"); 00689 default: 00690 throw new SQLException("Invalid ResultSet type"); 00691 } 00692 } 00693 00694 //--------------------------JDBC 3.0----------------------------- 00695 00696 /** 00697 * Moves to this <code>Statement</code> object's next result, deals with any 00698 * current <code>ResultSet</code> object(s) according to the instructions 00699 * specified by the given flag, and returns <code>true</code> if the next 00700 * result is a <code>ResultSet</code> object. 00701 * <p> 00702 * There are no more results when the following is <code>true</code>: 00703 * 00704 * <pre> 00705 * 00706 * 00707 * 00708 * 00709 * 00710 * 00711 * (!getMoreResults() && (getUpdateCount() == -1) 00712 * 00713 * 00714 * 00715 * 00716 * 00717 * 00718 * </pre> 00719 * 00720 * @param current one of the following <code>Statement</code> constants 00721 * indicating what should happen to current <code>ResultSet</code> 00722 * objects obtained using the method 00723 * <code>getResultSet</code: <code>CLOSE_CURRENT_RESULT</code>, 00724 * <code>KEEP_CURRENT_RESULT</code>, or <code>CLOSE_ALL_RESULTS</code> 00725 * @return <code>true</code> if the next result is a <code>ResultSet</code> 00726 * object; <code>false</code> if it is an update count or there are 00727 * no more results 00728 * @exception SQLException if a database access error occurs 00729 * @since JDK 1.4 00730 * @see #execute(String) 00731 */ 00732 public boolean getMoreResults(int current) throws SQLException 00733 { 00734 throw new NotImplementedException("getMoreResults"); 00735 } 00736 00737 /** 00738 * Retrieves any auto-generated keys created as a result of executing this 00739 * <code>Statement</code> object. If this <code>Statement</code> object 00740 * did not generate any keys, an empty <code>ResultSet</code> object is 00741 * returned. 00742 * 00743 * @return a <code>ResultSet</code> object containing the auto-generated 00744 * key(s) generated by the execution of this <code>Statement</code> 00745 * object 00746 * @exception SQLException if a database access error occurs 00747 * @since JDK 1.4 00748 */ 00749 public java.sql.ResultSet getGeneratedKeys() throws SQLException 00750 { 00751 return generatedKeys; 00752 } 00753 00754 /** 00755 * Executes the given SQL statement and signals the driver with the given flag 00756 * about whether the auto-generated keys produced by this 00757 * <code>Statement</code> object should be made available for retrieval. 00758 * 00759 * @param sql must be an SQL <code>INSERT</code>,<code>UPDATE</code> or 00760 * <code>DELETE</code> statement or an SQL statement that returns 00761 * nothing 00762 * @param autoGeneratedKeys a flag indicating whether auto-generated keys 00763 * should be made available for retrieval; one of the following 00764 * constants: <code>Statement.RETURN_GENERATED_KEYS</code> 00765 * <code>Statement.NO_GENERATED_KEYS</code> 00766 * @return either the row count for <code>INSERT</code>, 00767 * <code>UPDATE</code> or <code>DELETE</code> statements, or 00768 * <code>0</code> for SQL statements that return nothing 00769 * @exception SQLException if a database access error occurs, the given SQL 00770 * statement returns a <code>ResultSet</code> object, or the 00771 * given constant is not one of those allowed 00772 * @since JDK 1.4 00773 */ 00774 public int executeUpdate(String sql, int autoGeneratedKeys) 00775 throws SQLException 00776 { 00777 generatedKeysFlag = autoGeneratedKeys; 00778 return executeUpdate(sql); 00779 } 00780 00781 /** 00782 * Executes the given SQL statement and signals the driver that the 00783 * auto-generated keys indicated in the given array should be made available 00784 * for retrieval. The driver will ignore the array if the SQL statement is not 00785 * an <code>INSERT</code> statement. 00786 * 00787 * @param sql an SQL <code>INSERT</code>,<code>UPDATE</code> or 00788 * <code>DELETE</code> statement or an SQL statement that returns 00789 * nothing, such as an SQL DDL statement 00790 * @param columnIndexes an array of column indexes indicating the columns that 00791 * should be returned from the inserted row 00792 * @return either the row count for <code>INSERT</code>, 00793 * <code>UPDATE</code>, or <code>DELETE</code> statements, or 0 00794 * for SQL statements that return nothing 00795 * @exception SQLException if a database access error occurs or the SQL 00796 * statement returns a <code>ResultSet</code> object 00797 * @since JDK 1.4 00798 */ 00799 public int executeUpdate(String sql, int columnIndexes[]) throws SQLException 00800 { 00801 throw new NotImplementedException("executeUpdate"); 00802 } 00803 00804 /** 00805 * Executes the given SQL statement and signals the driver that the 00806 * auto-generated keys indicated in the given array should be made available 00807 * for retrieval. The driver will ignore the array if the SQL statement is not 00808 * an <code>INSERT</code> statement. 00809 * 00810 * @param sql an SQL <code>INSERT</code>,<code>UPDATE</code> or 00811 * <code>DELETE</code> statement or an SQL statement that returns 00812 * nothing 00813 * @param columnNames an array of the names of the columns that should be 00814 * returned from the inserted row 00815 * @return either the row count for <code>INSERT</code>, 00816 * <code>UPDATE</code>, or <code>DELETE</code> statements, or 0 00817 * for SQL statements that return nothing 00818 * @exception SQLException if a database access error occurs 00819 * @since JDK 1.4 00820 */ 00821 public int executeUpdate(String sql, String columnNames[]) 00822 throws SQLException 00823 { 00824 throw new NotImplementedException("executeUpdate"); 00825 } 00826 00827 /** 00828 * Executes the given SQL statement, which may return multiple results, and 00829 * signals the driver that any auto-generated keys should be made available 00830 * for retrieval. The driver will ignore this signal if the SQL statement is 00831 * not an <code>INSERT</code> statement. 00832 * <p> 00833 * In some (uncommon) situations, a single SQL statement may return multiple 00834 * result sets and/or update counts. Normally you can ignore this unless you 00835 * are (1) executing a stored procedure that you know may return multiple 00836 * results or (2) you are dynamically executing an unknown SQL string. 00837 * <p> 00838 * The <code>execute</code> method executes an SQL statement and indicates 00839 * the form of the first result. You must then use the methods 00840 * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve 00841 * the result, and <code>getMoreResults</code> to move to any subsequent 00842 * result(s). 00843 * 00844 * @param sql any SQL statement 00845 * @param autoGeneratedKeys a constant indicating whether auto-generated keys 00846 * should be made available for retrieval using the method 00847 * <code>getGeneratedKeys</code>; one of the following constants: 00848 * <code>Statement.RETURN_GENERATED_KEYS</code> or 00849 * <code>Statement.NO_GENERATED_KEYS</code> 00850 * @return <code>true</code> if the first result is a <code>ResultSet</code> 00851 * object; <code>false</code> if it is an update count or there are 00852 * no results 00853 * @exception SQLException if a database access error occurs 00854 * @see #getResultSet 00855 * @see #getUpdateCount 00856 * @see #getMoreResults() 00857 * @see #getGeneratedKeys 00858 * @since JDK 1.4 00859 */ 00860 public boolean execute(String sql, int autoGeneratedKeys) throws SQLException 00861 { 00862 generatedKeysFlag = autoGeneratedKeys; 00863 return execute(sql); 00864 } 00865 00866 /** 00867 * Executes the given SQL statement, which may return multiple results, and 00868 * signals the driver that the auto-generated keys indicated in the given 00869 * array should be made available for retrieval. This array contains the 00870 * indexes of the columns in the target table that contain the auto-generated 00871 * keys that should be made available. The driver will ignore the array if the 00872 * given SQL statement is not an <code>INSERT</code> statement. 00873 * <p> 00874 * Under some (uncommon) situations, a single SQL statement may return 00875 * multiple result sets and/or update counts. Normally you can ignore this 00876 * unless you are (1) executing a stored procedure that you know may return 00877 * multiple results or (2) you are dynamically executing an unknown SQL 00878 * string. 00879 * <p> 00880 * The <code>execute</code> method executes an SQL statement and indicates 00881 * the form of the first result. You must then use the methods 00882 * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve 00883 * the result, and <code>getMoreResults</code> to move to any subsequent 00884 * result(s). 00885 * 00886 * @param sql any SQL statement 00887 * @param columnIndexes an array of the indexes of the columns in the inserted 00888 * row that should be made available for retrieval by a call to the 00889 * method <code>getGeneratedKeys</code> 00890 * @return <code>true</code> if the first result is a <code>ResultSet</code> 00891 * object; <code>false</code> if it is an update count or there are 00892 * no results 00893 * @exception SQLException if a database access error occurs 00894 * @see #getResultSet 00895 * @see #getUpdateCount 00896 * @see #getMoreResults() 00897 * @since JDK 1.4 00898 */ 00899 public boolean execute(String sql, int columnIndexes[]) throws SQLException 00900 { 00901 throw new NotImplementedException("execute"); 00902 } 00903 00904 /** 00905 * Executes the given SQL statement, which may return multiple results, and 00906 * signals the driver that the auto-generated keys indicated in the given 00907 * array should be made available for retrieval. This array contains the names 00908 * of the columns in the target table that contain the auto-generated keys 00909 * that should be made available. The driver will ignore the array if the 00910 * given SQL statement is not an <code>INSERT</code> statement. 00911 * <p> 00912 * In some (uncommon) situations, a single SQL statement may return multiple 00913 * result sets and/or update counts. Normally you can ignore this unless you 00914 * are (1) executing a stored procedure that you know may return multiple 00915 * results or (2) you are dynamically executing an unknown SQL string. 00916 * <p> 00917 * The <code>execute</code> method executes an SQL statement and indicates 00918 * the form of the first result. You must then use the methods 00919 * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve 00920 * the result, and <code>getMoreResults</code> to move to any subsequent 00921 * result(s). 00922 * 00923 * @param sql any SQL statement 00924 * @param columnNames an array of the names of the columns in the inserted row 00925 * that should be made available for retrieval by a call to the 00926 * method <code>getGeneratedKeys</code> 00927 * @return <code>true</code> if the next result is a <code>ResultSet</code> 00928 * object; <code>false</code> if it is an update count or there are 00929 * no more results 00930 * @exception SQLException if a database access error occurs 00931 * @see #getResultSet 00932 * @see #getUpdateCount 00933 * @see #getMoreResults() 00934 * @see #getGeneratedKeys 00935 * @since JDK 1.4 00936 */ 00937 public boolean execute(String sql, String columnNames[]) throws SQLException 00938 { 00939 throw new NotImplementedException("execute"); 00940 } 00941 00942 /** 00943 * Retrieves the result set holdability for <code>ResultSet</code> objects 00944 * generated by this <code>Statement</code> object. 00945 * 00946 * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or 00947 * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code> 00948 * @exception SQLException if a database access error occurs 00949 * @since JDK 1.4 00950 */ 00951 public int getResultSetHoldability() throws SQLException 00952 { 00953 throw new NotImplementedException("getResultSetHoldability"); 00954 } 00955 }