001: //
002: // Copyright 1998, 1999 CDS Networks, Inc., Medford Oregon
003: //
004: // All rights reserved.
005: //
006: // Redistribution and use in source and binary forms, with or without
007: // modification, are permitted provided that the following conditions are met:
008: // 1. Redistributions of source code must retain the above copyright
009: // notice, this list of conditions and the following disclaimer.
010: // 2. Redistributions in binary form must reproduce the above copyright
011: // notice, this list of conditions and the following disclaimer in the
012: // documentation and/or other materials provided with the distribution.
013: // 3. All advertising materials mentioning features or use of this software
014: // must display the following acknowledgement:
015: // This product includes software developed by CDS Networks, Inc.
016: // 4. The name of CDS Networks, Inc. may not be used to endorse or promote
017: // products derived from this software without specific prior
018: // written permission.
019: //
020: // THIS SOFTWARE IS PROVIDED BY CDS NETWORKS, INC. ``AS IS'' AND
021: // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
022: // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
023: // ARE DISCLAIMED. IN NO EVENT SHALL CDS NETWORKS, INC. BE LIABLE
024: // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
025: // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
026: // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
027: // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
028: // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
029: // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
030: // SUCH DAMAGE.
031: //
032:
033: package com.internetcds.jdbc.tds;
034:
035: import java.sql.*;
036: import java.math.BigDecimal;
037: import java.util.Calendar;
038:
039: /**
040: * <P>CallableStatement is used to execute SQL stored procedures.
041: *
042: * <P>JDBC provides a stored procedure SQL escape that allows stored
043: * procedures to be called in a standard way for all RDBMS's. This
044: * escape syntax has one form that includes a result parameter and one
045: * that does not. If used, the result parameter must be registered as
046: * an OUT parameter. The other parameters may be used for input,
047: * output or both. Parameters are refered to sequentially, by
048: * number. The first parameter is 1.
049: *
050: * <P><CODE>
051: * {?= call <procedure-name>[<arg1>,<arg2>, ...]}<BR>
052: * {call <procedure-name>[<arg1>,<arg2>, ...]}
053: * </CODE>
054: *
055: * <P>IN parameter values are set using the set methods inherited from
056: * PreparedStatement. The type of all OUT parameters must be
057: * registered prior to executing the stored procedure; their values
058: * are retrieved after execution via the get methods provided here.
059: *
060: * <P>A Callable statement may return a ResultSet or multiple
061: * ResultSets. Multiple ResultSets are handled using operations
062: * inherited from Statement.
063: *
064: * <P>For maximum portability, a call's ResultSets and update counts
065: * should be processed prior to getting the values of output
066: * parameters.
067: *
068: * @see Connection#prepareCall
069: * @see ResultSet
070: */
071: public class CallableStatement_base extends
072: com.internetcds.jdbc.tds.PreparedStatement_base {
073: public static final String cvsVersion = "$Id: CallableStatement_base.java,v 1.2 2007-10-19 13:21:40 sinisa Exp $";
074:
075: private String procedureName = null;
076:
077: public CallableStatement_base(java.sql.Connection conn_, Tds tds_,
078: String sql) throws SQLException {
079: super (conn_, tds_, sql);
080: int i;
081: procedureName = "";
082: i = 0;
083: while (i < sql.length()
084: && (!(Character.isLetterOrDigit(sql.charAt(i)) || sql
085: .charAt(i) == '#'))) {
086: i++;
087: }
088:
089: while (i < sql.length()
090: && (Character.isLetterOrDigit(sql.charAt(i))
091: || sql.charAt(i) == '#' || sql.charAt(i) == '_')) {
092: procedureName = procedureName + sql.charAt(i);
093: i++;
094: }
095:
096: if (procedureName.length() == 0) {
097: throw new SQLException("Did not find name in sql string");
098: }
099: }
100:
101: /**
102: * Get the value of a NUMERIC parameter as a java.math.BigDecimal object.
103: *
104: * @param parameterIndex the first parameter is 1, the second is 2, ...
105: *
106: * @param scale a value greater than or equal to zero representing the
107: * desired number of digits to the right of the decimal point
108: *
109: * @return the parameter value; if the value is SQL NULL, the result is
110: * null
111: * @exception SQLException if a database-access error occurs.
112: */
113: public BigDecimal getBigDecimal(int parameterIndex, int scale)
114: throws SQLException {
115: throw new SQLException("Not implemented");
116: }
117:
118: /**
119: * Get the value of a BIT parameter as a Java boolean.
120: *
121: * @param parameterIndex the first parameter is 1, the second is 2, ...
122: * @return the parameter value; if the value is SQL NULL, the result is false
123: * @exception SQLException if a database-access error occurs.
124: */
125: public boolean getBoolean(int parameterIndex) throws SQLException {
126: throw new SQLException("Not implemented");
127: }
128:
129: /**
130: * Get the value of a TINYINT parameter as a Java byte.
131: *
132: * @param parameterIndex the first parameter is 1, the second is 2, ...
133: * @return the parameter value; if the value is SQL NULL, the result is 0
134: * @exception SQLException if a database-access error occurs.
135: */
136: public byte getByte(int parameterIndex) throws SQLException {
137: throw new SQLException("Not implemented");
138: }
139:
140: /**
141: * Get the value of a SQL BINARY or VARBINARY parameter as a Java byte[]
142: *
143: * @param parameterIndex the first parameter is 1, the second is 2, ...
144: * @return the parameter value; if the value is SQL NULL, the result is null
145: * @exception SQLException if a database-access error occurs.
146: */
147: public byte[] getBytes(int parameterIndex) throws SQLException {
148: throw new SQLException("Not implemented");
149: }
150:
151: /**
152: * Get the value of a SQL DATE parameter as a java.sql.Date object
153: *
154: * @param parameterIndex the first parameter is 1, the second is 2, ...
155: * @return the parameter value; if the value is SQL NULL, the result is null
156: * @exception SQLException if a database-access error occurs.
157: */
158: public java.sql.Date getDate(int parameterIndex)
159: throws SQLException {
160: throw new SQLException("Not implemented");
161: }
162:
163: /**
164: * Get the value of a DOUBLE parameter as a Java double.
165: *
166: * @param parameterIndex the first parameter is 1, the second is 2, ...
167: * @return the parameter value; if the value is SQL NULL, the result is 0
168: * @exception SQLException if a database-access error occurs.
169: */
170: public double getDouble(int parameterIndex) throws SQLException {
171: throw new SQLException("Not implemented");
172: }
173:
174: /**
175: * Get the value of a FLOAT parameter as a Java float.
176: *
177: * @param parameterIndex the first parameter is 1, the second is 2, ...
178: * @return the parameter value; if the value is SQL NULL, the result is 0
179: * @exception SQLException if a database-access error occurs.
180: */
181: public float getFloat(int parameterIndex) throws SQLException {
182: throw new SQLException("Not implemented");
183: }
184:
185: /**
186: * Get the value of an INTEGER parameter as a Java int.
187: *
188: * @param parameterIndex the first parameter is 1, the second is 2, ...
189: * @return the parameter value; if the value is SQL NULL, the result is 0
190: * @exception SQLException if a database-access error occurs.
191: */
192: public int getInt(int parameterIndex) throws SQLException {
193: throw new SQLException("Not implemented");
194: }
195:
196: /**
197: * Get the value of a BIGINT parameter as a Java long.
198: *
199: * @param parameterIndex the first parameter is 1, the second is 2, ...
200: * @return the parameter value; if the value is SQL NULL, the result is 0
201: * @exception SQLException if a database-access error occurs.
202: */
203: public long getLong(int parameterIndex) throws SQLException {
204: throw new SQLException("Not implemented");
205: }
206:
207: //----------------------------------------------------------------------
208: // Advanced features:
209:
210: /**
211: * Get the value of a parameter as a Java object.
212: *
213: * <p>This method returns a Java object whose type coresponds to the SQL
214: * type that was registered for this parameter using registerOutParameter.
215: *
216: * <p>Note that this method may be used to read
217: * datatabase-specific, abstract data types. This is done by
218: * specifying a targetSqlType of java.sql.types.OTHER, which
219: * allows the driver to return a database-specific Java type.
220: *
221: * @param parameterIndex The first parameter is 1, the second is 2, ...
222: * @return A java.lang.Object holding the OUT parameter value.
223: * @exception SQLException if a database-access error occurs.
224: * @see Types
225: */
226: public Object getObject(int parameterIndex) throws SQLException {
227: throw new SQLException("Not implemented");
228: }
229:
230: /**
231: * Get the value of a SMALLINT parameter as a Java short.
232: *
233: * @param parameterIndex the first parameter is 1, the second is 2, ...
234: * @return the parameter value; if the value is SQL NULL, the result is 0
235: * @exception SQLException if a database-access error occurs.
236: */
237: public short getShort(int parameterIndex) throws SQLException {
238: throw new SQLException("Not implemented");
239: }
240:
241: /**
242: * Get the value of a CHAR, VARCHAR, or LONGVARCHAR parameter as a Java String.
243: *
244: * @param parameterIndex the first parameter is 1, the second is 2, ...
245: * @return the parameter value; if the value is SQL NULL, the result is null
246: * @exception SQLException if a database-access error occurs.
247: */
248: public String getString(int parameterIndex) throws SQLException {
249: throw new SQLException("Not implemented");
250: }
251:
252: /**
253: * Get the value of a SQL TIME parameter as a java.sql.Time object.
254: *
255: * @param parameterIndex the first parameter is 1, the second is 2, ...
256: * @return the parameter value; if the value is SQL NULL, the result is null
257: * @exception SQLException if a database-access error occurs.
258: */
259: public java.sql.Time getTime(int parameterIndex)
260: throws SQLException {
261: throw new SQLException("Not implemented");
262: }
263:
264: /**
265: * Get the value of a SQL TIMESTAMP parameter as a java.sql.Timestamp object.
266: *
267: * @param parameterIndex the first parameter is 1, the second is 2, ...
268: * @return the parameter value; if the value is SQL NULL, the result is null
269: * @exception SQLException if a database-access error occurs.
270: */
271: public java.sql.Timestamp getTimestamp(int parameterIndex)
272: throws SQLException {
273: throw new SQLException("Not implemented");
274: }
275:
276: /**
277: * Before executing a stored procedure call, you must explicitly
278: * call registerOutParameter to register the java.sql.Type of each
279: * out parameter.
280: *
281: * <P><B>Note:</B> When reading the value of an out parameter, you
282: * must use the getXXX method whose Java type XXX corresponds to the
283: * parameter's registered SQL type.
284: *
285: * @param parameterIndex the first parameter is 1, the second is 2,...
286: * @param sqlType SQL type code defined by java.sql.Types;
287: * for parameters of type Numeric or Decimal use the version of
288: * registerOutParameter that accepts a scale value
289: * @exception SQLException if a database-access error occurs.
290: * @see Type
291: */
292: public void registerOutParameter(int parameterIndex, int sqlType)
293: throws SQLException {
294: throw new SQLException("Not implemented");
295: }
296:
297: /**
298: * Use this version of registerOutParameter for registering
299: * Numeric or Decimal out parameters.
300: *
301: * <P><B>Note:</B> When reading the value of an out parameter, you
302: * must use the getXXX method whose Java type XXX corresponds to the
303: * parameter's registered SQL type.
304: *
305: * @param parameterIndex the first parameter is 1, the second is 2, ...
306: * @param sqlType use either java.sql.Type.NUMERIC or java.sql.Type.DECIMAL
307: * @param scale a value greater than or equal to zero representing the
308: * desired number of digits to the right of the decimal point
309: * @exception SQLException if a database-access error occurs.
310: * @see Type
311: */
312: public void registerOutParameter(int parameterIndex, int sqlType,
313: int scale) throws SQLException {
314: throw new SQLException("Not implemented");
315: }
316:
317: /**
318: * An OUT parameter may have the value of SQL NULL; wasNull reports
319: * whether the last value read has this special value.
320: *
321: * <P><B>Note:</B> You must first call getXXX on a parameter to
322: * read its value and then call wasNull() to see if the value was
323: * SQL NULL.
324: *
325: * @return true if the last parameter read was SQL NULL
326: * @exception SQLException if a database-access error occurs.
327: */
328: public boolean wasNull() throws SQLException {
329: throw new SQLException("Not implemented");
330: }
331:
332: public boolean execute() throws SQLException {
333: boolean result;
334:
335: closeResults();
336: updateCount = -2;
337:
338: // First make sure the caller has filled in all the parameters.
339: ParameterUtils.verifyThatParametersAreSet(parameterList);
340:
341: // execute the stored procedure
342: result = executeCall(procedureName, parameterList,
343: parameterList);
344:
345: return result;
346: }
347:
348: //--------------------------JDBC 2.0-----------------------------
349:
350: /**
351: * JDBC 2.0
352: *
353: * Gets the value of a JDBC <code>NUMERIC</code> parameter as a
354: * <code>java.math.BigDecimal</code> object with as many digits to the
355: * right of the decimal point as the value contains.
356: * @param parameterIndex the first parameter is 1, the second is 2,
357: * and so on
358: * @return the parameter value in full precision. If the value is
359: * SQL NULL, the result is <code>null</code>.
360: * @exception SQLException if a database access error occurs
361: */
362: public BigDecimal getBigDecimal(int parameterIndex)
363: throws SQLException {
364: NotImplemented();
365: return null;
366: }
367:
368: /**
369: * Gets the value of a JDBC <code>DATE</code> parameter as a
370: * <code>java.sql.Date</code> object, using
371: * the given <code>Calendar</code> object
372: * to construct the date.
373: * With a <code>Calendar</code> object, the driver
374: * can calculate the date taking into account a custom timezone and locale.
375: * If no <code>Calendar</code> object is specified, the driver uses the
376: * default timezone and locale.
377: *
378: * @param parameterIndex the first parameter is 1, the second is 2,
379: * and so on
380: * @param cal the <code>Calendar</code> object the driver will use
381: * to construct the date
382: * @return the parameter value. If the value is SQL NULL, the result is
383: * <code>null</code>.
384: * @exception SQLException if a database access error occurs
385: */
386: public java.sql.Date getDate(int parameterIndex, Calendar cal)
387: throws SQLException {
388: NotImplemented();
389: return null;
390: }
391:
392: /**
393: * Gets the value of a JDBC <code>TIME</code> parameter as a
394: * <code>java.sql.Time</code> object, using
395: * the given <code>Calendar</code> object
396: * to construct the time.
397: * With a <code>Calendar</code> object, the driver
398: * can calculate the time taking into account a custom timezone and locale.
399: * If no <code>Calendar</code> object is specified, the driver uses the
400: * default timezone and locale.
401: *
402: * @param parameterIndex the first parameter is 1, the second is 2,
403: * and so on
404: * @param cal the <code>Calendar</code> object the driver will use
405: * to construct the time
406: * @return the parameter value; if the value is SQL NULL, the result is
407: * <code>null</code>.
408: * @exception SQLException if a database access error occurs
409: */
410: public java.sql.Time getTime(int parameterIndex, Calendar cal)
411: throws SQLException {
412: NotImplemented();
413: return null;
414: }
415:
416: /**
417: * Gets the value of a JDBC <code>TIMESTAMP</code> parameter as a
418: * <code>java.sql.Timestamp</code> object, using
419: * the given <code>Calendar</code> object to construct
420: * the <code>Timestamp</code> object.
421: * With a <code>Calendar</code> object, the driver
422: * can calculate the timestamp taking into account a custom timezone and locale.
423: * If no <code>Calendar</code> object is specified, the driver uses the
424: * default timezone and locale.
425: *
426: *
427: * @param parameterIndex the first parameter is 1, the second is 2,
428: * and so on
429: * @param cal the <code>Calendar</code> object the driver will use
430: * to construct the timestamp
431: * @return the parameter value. If the value is SQL NULL, the result is
432: * <code>null</code>.
433: * @exception SQLException if a database access error occurs
434: */
435: public java.sql.Timestamp getTimestamp(int parameterIndex,
436: Calendar cal) throws SQLException {
437: NotImplemented();
438: return null;
439: }
440:
441: /**
442: * JDBC 2.0
443: *
444: * Registers the designated output parameter. This version of
445: * the method <code>registerOutParameter</code>
446: * should be used for a user-named or REF output parameter. Examples
447: * of user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and
448: * named array types.
449: *
450: * Before executing a stored procedure call, you must explicitly
451: * call <code>registerOutParameter</code> to register the type from
452: * <code>java.sql.Types</code> for each
453: * OUT parameter. For a user-named parameter the fully-qualified SQL
454: * type name of the parameter should also be given, while a REF
455: * parameter requires that the fully-qualified type name of the
456: * referenced type be given. A JDBC driver that does not need the
457: * type code and type name information may ignore it. To be portable,
458: * however, applications should always provide these values for
459: * user-named and REF parameters.
460: *
461: * Although it is intended for user-named and REF parameters,
462: * this method may be used to register a parameter of any JDBC type.
463: * If the parameter does not have a user-named or REF type, the
464: * typeName parameter is ignored.
465: *
466: * <P><B>Note:</B> When reading the value of an out parameter, you
467: * must use the <code>getXXX</code> method whose Java type XXX corresponds to the
468: * parameter's registered SQL type.
469: *
470: * @param parameterIndex the first parameter is 1, the second is 2,...
471: * @param sqlType a value from {@link java.sql.Types}
472: * @param typeName the fully-qualified name of an SQL structured type
473: * @exception SQLException if a database-access error occurs
474: * @see Types
475: */
476: public void registerOutParameter(int paramIndex, int sqlType,
477: String typeName) throws SQLException {
478: NotImplemented();
479: }
480:
481: static public void main(String args[])
482: throws java.lang.ClassNotFoundException,
483: java.lang.IllegalAccessException,
484: java.lang.InstantiationException {
485: try {
486: String url = url = "" + "jdbc:freetds:" + "//" + "kap"
487: + "/" + "pubs";
488:
489: Class.forName("com.internetcds.jdbc.tds.Driver")
490: .newInstance();
491: java.sql.Connection connection;
492: connection = DriverManager.getConnection(url, "testuser",
493: "password");
494:
495: java.sql.CallableStatement call = connection
496: .prepareCall("sp_tables ?");
497: call.setString(1, "%");
498: java.sql.ResultSet rs = call.executeQuery();
499:
500: while (rs.next()) {
501: String qualifier = rs.getString("TABLE_QUALIFIER");
502: String owner = rs.getString("TABLE_OWNER");
503: String name = rs.getString("TABLE_NAME");
504: String type = rs.getString("TABLE_TYPE");
505: String remarks = rs.getString("REMARKS");
506:
507: System.out.println("qualifier: " + qualifier);
508: System.out.println("owner: " + owner);
509: System.out.println("name: " + name);
510: System.out.println("type: " + type);
511: System.out.println("remarks: " + remarks);
512: System.out.println("");
513: }
514: } catch (SQLException e) {
515: e.printStackTrace();
516: System.out.println(e.getMessage());
517: }
518: }
519: }
|