PreparedStatement.java
上传用户:psq1974
上传日期:2007-01-06
资源大小:1195k
文件大小:19k
源码类别:

mpeg/mp3

开发平台:

C/C++

  1. package postgresql;
  2. import java.io.*;
  3. import java.math.*;
  4. import java.sql.*;
  5. import java.text.*;
  6. import java.util.*;
  7. import postgresql.largeobject.*;
  8. import postgresql.util.*;
  9. /**
  10.  * A SQL Statement is pre-compiled and stored in a PreparedStatement object.
  11.  * This object can then be used to efficiently execute this statement multiple
  12.  * times.
  13.  *
  14.  * <p><B>Note:</B> The setXXX methods for setting IN parameter values must
  15.  * specify types that are compatible with the defined SQL type of the input
  16.  * parameter.  For instance, if the IN parameter has SQL type Integer, then
  17.  * setInt should be used.
  18.  *
  19.  * <p>If arbitrary parameter type conversions are required, then the setObject 
  20.  * method should be used with a target SQL type.
  21.  *
  22.  * @see ResultSet
  23.  * @see java.sql.PreparedStatement
  24.  */
  25. public class PreparedStatement extends Statement implements java.sql.PreparedStatement 
  26. {
  27. String sql;
  28. String[] templateStrings;
  29. String[] inStrings;
  30. Connection connection;
  31. /**
  32.  * Constructor for the PreparedStatement class.
  33.  * Split the SQL statement into segments - separated by the arguments.
  34.  * When we rebuild the thing with the arguments, we can substitute the
  35.  * args and join the whole thing together.
  36.  *
  37.  * @param conn the instanatiating connection
  38.  * @param sql the SQL statement with ? for IN markers
  39.  * @exception SQLException if something bad occurs
  40.  */
  41. public PreparedStatement(Connection connection, String sql) throws SQLException
  42. {
  43. super(connection);
  44. Vector v = new Vector();
  45. boolean inQuotes = false;
  46. int lastParmEnd = 0, i;
  47. this.sql = sql;
  48. this.connection = connection;
  49. for (i = 0; i < sql.length(); ++i)
  50. {
  51. int c = sql.charAt(i);
  52. if (c == ''')
  53. inQuotes = !inQuotes;
  54. if (c == '?' && !inQuotes)
  55. {
  56. v.addElement(sql.substring (lastParmEnd, i));
  57. lastParmEnd = i + 1;
  58. }
  59. }
  60. v.addElement(sql.substring (lastParmEnd, sql.length()));
  61. templateStrings = new String[v.size()];
  62. inStrings = new String[v.size() - 1];
  63. clearParameters();
  64. for (i = 0 ; i < templateStrings.length; ++i)
  65. templateStrings[i] = (String)v.elementAt(i);
  66. }
  67. /**
  68.  * A Prepared SQL query is executed and its ResultSet is returned
  69.  *
  70.  * @return a ResultSet that contains the data produced by the
  71.  * query - never null
  72.  * @exception SQLException if a database access error occurs
  73.  */
  74. public java.sql.ResultSet executeQuery() throws SQLException
  75. {
  76. StringBuffer s = new StringBuffer();
  77. int i;
  78. for (i = 0 ; i < inStrings.length ; ++i)
  79. {
  80. if (inStrings[i] == null)
  81. throw new SQLException("No value specified for parameter " + (i + 1));
  82. s.append (templateStrings[i]);
  83. s.append (inStrings[i]);
  84. }
  85. s.append(templateStrings[inStrings.length]);
  86. return super.executeQuery(s.toString());  // in Statement class
  87. }
  88. /**
  89.  * Execute a SQL INSERT, UPDATE or DELETE statement.  In addition,
  90.  * SQL statements that return nothing such as SQL DDL statements can
  91.  * be executed.
  92.  *
  93.  * @return either the row count for INSERT, UPDATE or DELETE; or
  94.  *  0 for SQL statements that return nothing.
  95.  * @exception SQLException if a database access error occurs
  96.  */
  97. public int executeUpdate() throws SQLException
  98. {
  99. StringBuffer s = new StringBuffer();
  100. int i;
  101. for (i = 0 ; i < inStrings.length ; ++i)
  102. {
  103. if (inStrings[i] == null)
  104. throw new SQLException("No value specified for parameter " + (i + 1));
  105. s.append (templateStrings[i]);
  106. s.append (inStrings[i]);
  107. }
  108. s.append(templateStrings[inStrings.length]);
  109. return super.executeUpdate(s.toString());  // in Statement class
  110. }
  111. /**
  112.  * Set a parameter to SQL NULL
  113.  *
  114.  * <p><B>Note:</B> You must specify the parameters SQL type (although
  115.  * PostgreSQL ignores it)
  116.  *
  117.  * @param parameterIndex the first parameter is 1, etc...
  118.  * @param sqlType the SQL type code defined in java.sql.Types
  119.  * @exception SQLException if a database access error occurs
  120.  */
  121. public void setNull(int parameterIndex, int sqlType) throws SQLException
  122. {
  123. set(parameterIndex, "null");
  124. }
  125. /**
  126.  * Set a parameter to a Java boolean value.  The driver converts this
  127.  * to a SQL BIT value when it sends it to the database.
  128.  *
  129.  * @param parameterIndex the first parameter is 1...
  130.  * @param x the parameter value
  131.  * @exception SQLException if a database access error occurs
  132.  */
  133. public void setBoolean(int parameterIndex, boolean x) throws SQLException
  134. {
  135. set(parameterIndex, x ? "'t'" : "'f'");
  136. }
  137. /**
  138.  * Set a parameter to a Java byte value.  The driver converts this to
  139.  * a SQL TINYINT value when it sends it to the database.
  140.  *
  141.  * @param parameterIndex the first parameter is 1...
  142.  * @param x the parameter value
  143.  * @exception SQLException if a database access error occurs
  144.  */
  145. public void setByte(int parameterIndex, byte x) throws SQLException
  146. {
  147. set(parameterIndex, (new Integer(x)).toString());
  148. }
  149. /**
  150.  * Set a parameter to a Java short value.  The driver converts this
  151.  * to a SQL SMALLINT value when it sends it to the database.
  152.  *
  153.  * @param parameterIndex the first parameter is 1...
  154.  * @param x the parameter value
  155.  * @exception SQLException if a database access error occurs
  156.  */
  157. public void setShort(int parameterIndex, short x) throws SQLException
  158. {
  159. set(parameterIndex, (new Integer(x)).toString());
  160. }
  161. /**
  162.  * Set a parameter to a Java int value.  The driver converts this to
  163.  * a SQL INTEGER value when it sends it to the database.
  164.  *
  165.  * @param parameterIndex the first parameter is 1...
  166.  * @param x the parameter value
  167.  * @exception SQLException if a database access error occurs
  168.  */
  169. public void setInt(int parameterIndex, int x) throws SQLException
  170. {
  171. set(parameterIndex, (new Integer(x)).toString());
  172. }
  173. /**
  174.  * Set a parameter to a Java long value.  The driver converts this to
  175.  * a SQL BIGINT value when it sends it to the database.
  176.  *
  177.  * @param parameterIndex the first parameter is 1...
  178.  * @param x the parameter value
  179.  * @exception SQLException if a database access error occurs
  180.  */
  181. public void setLong(int parameterIndex, long x) throws SQLException
  182. {
  183. set(parameterIndex, (new Long(x)).toString());
  184. }
  185. /**
  186.  * Set a parameter to a Java float value.  The driver converts this
  187.  * to a SQL FLOAT value when it sends it to the database.
  188.  *
  189.  * @param parameterIndex the first parameter is 1...
  190.  * @param x the parameter value
  191.  * @exception SQLException if a database access error occurs
  192.  */
  193. public void setFloat(int parameterIndex, float x) throws SQLException
  194. {
  195. set(parameterIndex, (new Float(x)).toString());
  196. }
  197. /**
  198.  * Set a parameter to a Java double value.  The driver converts this
  199.  * to a SQL DOUBLE value when it sends it to the database
  200.  *
  201.  * @param parameterIndex the first parameter is 1...
  202.  * @param x the parameter value
  203.  * @exception SQLException if a database access error occurs
  204.  */
  205. public void setDouble(int parameterIndex, double x) throws SQLException
  206. {
  207. set(parameterIndex, (new Double(x)).toString());
  208. }
  209. /**
  210.  * Set a parameter to a java.lang.BigDecimal value.  The driver
  211.  * converts this to a SQL NUMERIC value when it sends it to the
  212.  * database.
  213.  *
  214.  * @param parameterIndex the first parameter is 1...
  215.  * @param x the parameter value
  216.  * @exception SQLException if a database access error occurs
  217.  */
  218. public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException
  219. {
  220. set(parameterIndex, x.toString());
  221. }
  222. /**
  223.  * Set a parameter to a Java String value.  The driver converts this
  224.  * to a SQL VARCHAR or LONGVARCHAR value (depending on the arguments
  225.  * size relative to the driver's limits on VARCHARs) when it sends it
  226.  * to the database.
  227.  *
  228.  * @param parameterIndex the first parameter is 1...
  229.  * @param x the parameter value
  230.  * @exception SQLException if a database access error occurs
  231.  */
  232. public void setString(int parameterIndex, String x) throws SQLException
  233. {
  234.   // if the passed string is null, then set this column to null
  235.   if(x==null)
  236.     set(parameterIndex,"null");
  237.   else {
  238.     StringBuffer b = new StringBuffer();
  239.     int i;
  240.     
  241.     b.append(''');
  242.     for (i = 0 ; i < x.length() ; ++i)
  243.       {
  244. char c = x.charAt(i);
  245. if (c == '\' || c == ''')
  246.   b.append((char)'\');
  247. b.append(c);
  248.       }
  249.     b.append(''');
  250.     set(parameterIndex, b.toString());
  251.   }
  252. }
  253.   /**
  254.    * Set a parameter to a Java array of bytes.  The driver converts this
  255.    * to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
  256.    * size relative to the driver's limits on VARBINARYs) when it sends
  257.    * it to the database.
  258.    *
  259.    * <p>Implementation note:
  260.    * <br>With postgresql, this creates a large object, and stores the
  261.    * objects oid in this column.
  262.    *
  263.    * @param parameterIndex the first parameter is 1...
  264.    * @param x the parameter value
  265.    * @exception SQLException if a database access error occurs
  266.    */
  267.   public void setBytes(int parameterIndex, byte x[]) throws SQLException
  268.   {
  269.     LargeObjectManager lom = connection.getLargeObjectAPI();
  270.     int oid = lom.create();
  271.     LargeObject lob = lom.open(oid);
  272.     lob.write(x);
  273.     lob.close();
  274.     setInt(parameterIndex,oid);
  275.   }
  276. /**
  277.  * Set a parameter to a java.sql.Date value.  The driver converts this
  278.  * to a SQL DATE value when it sends it to the database.
  279.  *
  280.  * @param parameterIndex the first parameter is 1...
  281.  * @param x the parameter value
  282.  * @exception SQLException if a database access error occurs
  283.  */
  284. public void setDate(int parameterIndex, java.sql.Date x) throws SQLException
  285. {
  286.   SimpleDateFormat df = new SimpleDateFormat("''"+connection.getDateStyle()+"''");
  287.   
  288.   set(parameterIndex, df.format(x));
  289.   
  290.   // The above is how the date should be handled.
  291.   //
  292.   // However, in JDK's prior to 1.1.6 (confirmed with the
  293.   // Linux jdk1.1.3 and the Win95 JRE1.1.5), SimpleDateFormat seems
  294.   // to format a date to the previous day. So the fix is to add a day
  295.   // before formatting.
  296.   //
  297.   // PS: 86400000 is one day
  298.   //
  299.   //set(parameterIndex, df.format(new java.util.Date(x.getTime()+86400000)));
  300. }
  301.   
  302. /**
  303.  * Set a parameter to a java.sql.Time value.  The driver converts
  304.  * this to a SQL TIME value when it sends it to the database.
  305.  *
  306.  * @param parameterIndex the first parameter is 1...));
  307.  * @param x the parameter value
  308.  * @exception SQLException if a database access error occurs
  309.  */
  310. public void setTime(int parameterIndex, Time x) throws SQLException
  311. {
  312. set(parameterIndex, "'" + x.toString() + "'");
  313. }
  314. /**
  315.  * Set a parameter to a java.sql.Timestamp value.  The driver converts
  316.  * this to a SQL TIMESTAMP value when it sends it to the database.
  317.  *
  318.  * @param parameterIndex the first parameter is 1...
  319.  * @param x the parameter value
  320.  * @exception SQLException if a database access error occurs
  321.  */
  322. public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
  323. {
  324. set(parameterIndex, "'" + x.toString() + "'");
  325. }
  326. /**
  327.  * When a very large ASCII value is input to a LONGVARCHAR parameter,
  328.  * it may be more practical to send it via a java.io.InputStream.
  329.  * JDBC will read the data from the stream as needed, until it reaches
  330.  * end-of-file.  The JDBC driver will do any necessary conversion from
  331.  * ASCII to the database char format.
  332.  *
  333.  * <P><B>Note:</B> This stream object can either be a standard Java
  334.  * stream object or your own subclass that implements the standard
  335.  * interface.
  336.  *
  337.  * @param parameterIndex the first parameter is 1...
  338.  * @param x the parameter value
  339.  * @param length the number of bytes in the stream
  340.  * @exception SQLException if a database access error occurs
  341.  */
  342. public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException
  343. {
  344. setBinaryStream(parameterIndex, x, length);
  345. }
  346. /**
  347.  * When a very large Unicode value is input to a LONGVARCHAR parameter,
  348.  * it may be more practical to send it via a java.io.InputStream.
  349.  * JDBC will read the data from the stream as needed, until it reaches
  350.  * end-of-file.  The JDBC driver will do any necessary conversion from
  351.  * UNICODE to the database char format.
  352.  *
  353.  * <P><B>Note:</B> This stream object can either be a standard Java
  354.  * stream object or your own subclass that implements the standard
  355.  * interface.
  356.  *
  357.  * @param parameterIndex the first parameter is 1...
  358.  * @param x the parameter value
  359.  * @exception SQLException if a database access error occurs
  360.  */
  361. public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException
  362. {
  363. setBinaryStream(parameterIndex, x, length);
  364. }
  365. /**
  366.  * When a very large binary value is input to a LONGVARBINARY parameter,
  367.  * it may be more practical to send it via a java.io.InputStream.
  368.  * JDBC will read the data from the stream as needed, until it reaches
  369.  * end-of-file.  
  370.  *
  371.  * <P><B>Note:</B> This stream object can either be a standard Java
  372.  * stream object or your own subclass that implements the standard
  373.  * interface.
  374.  *
  375.  * @param parameterIndex the first parameter is 1...
  376.  * @param x the parameter value
  377.  * @exception SQLException if a database access error occurs
  378.  */
  379. public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException
  380. {
  381. throw new SQLException("InputStream as parameter not supported");
  382. }
  383. /**
  384.  * In general, parameter values remain in force for repeated used of a
  385.  * Statement.  Setting a parameter value automatically clears its
  386.  * previous value.  However, in coms cases, it is useful to immediately
  387.  * release the resources used by the current parameter values; this
  388.  * can be done by calling clearParameters
  389.  *
  390.  * @exception SQLException if a database access error occurs
  391.  */
  392. public void clearParameters() throws SQLException
  393. {
  394. int i;
  395. for (i = 0 ; i < inStrings.length ; i++)
  396. inStrings[i] = null;
  397. }
  398. /**
  399.  * Set the value of a parameter using an object; use the java.lang
  400.  * equivalent objects for integral values.
  401.  *
  402.  * <P>The given Java object will be converted to the targetSqlType before
  403.  * being sent to the database.
  404.  *
  405.  * <P>note that this method may be used to pass database-specific
  406.  * abstract data types.  This is done by using a Driver-specific
  407.  * Java type and using a targetSqlType of java.sql.Types.OTHER
  408.  *
  409.  * @param parameterIndex the first parameter is 1...
  410.  * @param x the object containing the input parameter value
  411.  * @param targetSqlType The SQL type to be send to the database
  412.  * @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC
  413.  * types this is the number of digits after the decimal.  For 
  414.  * all other types this value will be ignored.
  415.  * @exception SQLException if a database access error occurs
  416.  */
  417. public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException
  418. {
  419. switch (targetSqlType)
  420. {
  421. case Types.TINYINT:
  422. case Types.SMALLINT:
  423. case Types.INTEGER:
  424. case Types.BIGINT:
  425. case Types.REAL:
  426. case Types.FLOAT:
  427. case Types.DOUBLE:
  428. case Types.DECIMAL:
  429. case Types.NUMERIC:
  430. if (x instanceof Boolean)
  431. set(parameterIndex, ((Boolean)x).booleanValue() ? "1" : "0");
  432. else
  433. set(parameterIndex, x.toString());
  434. break;
  435. case Types.CHAR:
  436. case Types.VARCHAR:
  437. case Types.LONGVARCHAR:
  438. setString(parameterIndex, x.toString());
  439. break;
  440. case Types.DATE:
  441. setDate(parameterIndex, (java.sql.Date)x);
  442. break;
  443. case Types.TIME:
  444. setTime(parameterIndex, (Time)x);
  445. break;
  446. case Types.TIMESTAMP:
  447. setTimestamp(parameterIndex, (Timestamp)x);
  448. break;
  449. case Types.OTHER:
  450. setString(parameterIndex, ((PGobject)x).getValue());
  451. break;
  452. default:
  453. throw new SQLException("Unknown Types value");
  454. }
  455. }
  456. public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException
  457. {
  458. setObject(parameterIndex, x, targetSqlType, 0);
  459. }
  460.   /**
  461.    * This stores an Object into a parameter.
  462.    * <p>New for 6.4, if the object is not recognised, but it is
  463.    * Serializable, then the object is serialised using the
  464.    * postgresql.util.Serialize class.
  465.    */
  466. public void setObject(int parameterIndex, Object x) throws SQLException
  467. {
  468. if (x instanceof String)
  469. setString(parameterIndex, (String)x);
  470. else if (x instanceof BigDecimal)
  471. setBigDecimal(parameterIndex, (BigDecimal)x);
  472. else if (x instanceof Short)
  473. setShort(parameterIndex, ((Short)x).shortValue());
  474. else if (x instanceof Integer)
  475. setInt(parameterIndex, ((Integer)x).intValue());
  476. else if (x instanceof Long)
  477. setLong(parameterIndex, ((Long)x).longValue());
  478. else if (x instanceof Float)
  479. setFloat(parameterIndex, ((Float)x).floatValue());
  480. else if (x instanceof Double)
  481. setDouble(parameterIndex, ((Double)x).doubleValue());
  482. else if (x instanceof byte[])
  483. setBytes(parameterIndex, (byte[])x);
  484. else if (x instanceof java.sql.Date)
  485. setDate(parameterIndex, (java.sql.Date)x);
  486. else if (x instanceof Time)
  487. setTime(parameterIndex, (Time)x);
  488. else if (x instanceof Timestamp)
  489. setTimestamp(parameterIndex, (Timestamp)x);
  490. else if (x instanceof Boolean)
  491. setBoolean(parameterIndex, ((Boolean)x).booleanValue());
  492. else if (x instanceof PGobject)
  493. setString(parameterIndex, ((PGobject)x).getValue());
  494. else
  495. setLong(parameterIndex, connection.putObject(x));
  496. }
  497. /**
  498.  * Some prepared statements return multiple results; the execute method
  499.  * handles these complex statements as well as the simpler form of 
  500.  * statements handled by executeQuery and executeUpdate
  501.  *
  502.  * @return true if the next result is a ResultSet; false if it is an
  503.  * update count or there are no more results
  504.  * @exception SQLException if a database access error occurs
  505.  */
  506. public boolean execute() throws SQLException
  507. {
  508. StringBuffer s = new StringBuffer();
  509. int i;
  510. for (i = 0 ; i < inStrings.length ; ++i)
  511. {
  512. if (inStrings[i] == null)
  513. throw new SQLException("No value specified for parameter " + (i + 1));
  514. s.append (templateStrings[i]);
  515. s.append (inStrings[i]);
  516. }
  517. s.append(templateStrings[inStrings.length]);
  518. return super.execute(s.toString());  // in Statement class
  519. }
  520. /**
  521.  * Returns the SQL statement with the current template values
  522.  * substituted.
  523.  */
  524. public String toString() {
  525. StringBuffer s = new StringBuffer();
  526. int i;
  527. for (i = 0 ; i < inStrings.length ; ++i)
  528. {
  529. if (inStrings[i] == null)
  530. s.append( '?' );
  531. else
  532. s.append (templateStrings[i]);
  533. s.append (inStrings[i]);
  534. }
  535. s.append(templateStrings[inStrings.length]);
  536. return s.toString();
  537. }
  538. // **************************************************************
  539. // END OF PUBLIC INTERFACE
  540. // **************************************************************
  541. /**
  542.  * There are a lot of setXXX classes which all basically do
  543.  * the same thing.  We need a method which actually does the
  544.  * set for us.
  545.  *
  546.  * @param paramIndex the index into the inString
  547.  * @param s a string to be stored
  548.  * @exception SQLException if something goes wrong
  549.  */
  550. private void set(int paramIndex, String s) throws SQLException
  551. {
  552. if (paramIndex < 1 || paramIndex > inStrings.length)
  553. throw new SQLException("Parameter index out of range");
  554. inStrings[paramIndex - 1] = s;
  555. }
  556. }