@@ -209,141 +209,26 @@ are passed in as a parameter to the stored procedure.
209
209
210
210
The `SqlReturnType` interface has a single method (named `getTypeValue`) that must be
211
211
implemented. This interface is used as part of the declaration of an `SqlOutParameter`.
212
- The following example shows returning the value of an Oracle `STRUCT ` object of the user
212
+ The following example shows returning the value of a `java.sql.Struct ` object of the user
213
213
declared type `ITEM_TYPE`:
214
214
215
- [tabs]
216
- ======
217
- Java::
218
- +
219
- [source,java,indent=0,subs="verbatim,quotes",role="primary"]
220
- ----
221
- public class TestItemStoredProcedure extends StoredProcedure {
222
-
223
- public TestItemStoredProcedure(DataSource dataSource) {
224
- // ...
225
- declareParameter(new SqlOutParameter("item", OracleTypes.STRUCT, "ITEM_TYPE",
226
- (CallableStatement cs, int colIndx, int sqlType, String typeName) -> {
227
- STRUCT struct = (STRUCT) cs.getObject(colIndx);
228
- Object[] attr = struct.getAttributes();
229
- TestItem item = new TestItem();
230
- item.setId(((Number) attr[0]).longValue());
231
- item.setDescription((String) attr[1]);
232
- item.setExpirationDate((java.util.Date) attr[2]);
233
- return item;
234
- }));
235
- // ...
236
- }
237
- ----
238
-
239
- Kotlin::
240
- +
241
- [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
242
- ----
243
- class TestItemStoredProcedure(dataSource: DataSource) : StoredProcedure() {
244
-
245
- init {
246
- // ...
247
- declareParameter(SqlOutParameter("item", OracleTypes.STRUCT, "ITEM_TYPE") { cs, colIndx, sqlType, typeName ->
248
- val struct = cs.getObject(colIndx) as STRUCT
249
- val attr = struct.getAttributes()
250
- TestItem((attr[0] as Long, attr[1] as String, attr[2] as Date)
251
- })
252
- // ...
253
- }
254
- }
255
- ----
256
- ======
215
+ include-code::./TestItemStoredProcedure[]
257
216
258
217
You can use `SqlTypeValue` to pass the value of a Java object (such as `TestItem`) to a
259
218
stored procedure. The `SqlTypeValue` interface has a single method (named
260
219
`createTypeValue`) that you must implement. The active connection is passed in, and you
261
- can use it to create database-specific objects, such as `StructDescriptor` instances
262
- or `ArrayDescriptor` instances. The following example creates a `StructDescriptor` instance:
263
-
264
- [tabs]
265
- ======
266
- Java::
267
- +
268
- [source,java,indent=0,subs="verbatim,quotes",role="primary"]
269
- ----
270
- final TestItem testItem = new TestItem(123L, "A test item",
271
- new SimpleDateFormat("yyyy-M-d").parse("2010-12-31"));
272
-
273
- SqlTypeValue value = new AbstractSqlTypeValue() {
274
- protected Object createTypeValue(Connection conn, int sqlType, String typeName) throws SQLException {
275
- StructDescriptor itemDescriptor = new StructDescriptor(typeName, conn);
276
- Struct item = new STRUCT(itemDescriptor, conn,
277
- new Object[] {
278
- testItem.getId(),
279
- testItem.getDescription(),
280
- new java.sql.Date(testItem.getExpirationDate().getTime())
281
- });
282
- return item;
283
- }
284
- };
285
- ----
220
+ can use it to create database-specific objects, such as `java.sql.Struct` instances
221
+ or `java.sql.Array` instances. The following example creates a `java.sql.Struct` instance:
286
222
287
- Kotlin::
288
- +
289
- [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
290
- ----
291
- val (id, description, expirationDate) = TestItem(123L, "A test item",
292
- SimpleDateFormat("yyyy-M-d").parse("2010-12-31"))
293
-
294
- val value = object : AbstractSqlTypeValue() {
295
- override fun createTypeValue(conn: Connection, sqlType: Int, typeName: String?): Any {
296
- val itemDescriptor = StructDescriptor(typeName, conn)
297
- return STRUCT(itemDescriptor, conn,
298
- arrayOf(id, description, java.sql.Date(expirationDate.time)))
299
- }
300
- }
301
- ----
302
- ======
223
+ include-code::./SqlTypeValueFactory[tag=struct,indent=0]
303
224
304
225
You can now add this `SqlTypeValue` to the `Map` that contains the input parameters for the
305
226
`execute` call of the stored procedure.
306
227
307
228
Another use for the `SqlTypeValue` is passing in an array of values to an Oracle stored
308
- procedure. Oracle has its own internal `ARRAY` class that must be used in this case, and
309
- you can use the `SqlTypeValue` to create an instance of the Oracle `ARRAY` and populate
310
- it with values from the Java `ARRAY`, as the following example shows:
311
-
312
- [tabs]
313
- ======
314
- Java::
315
- +
316
- [source,java,indent=0,subs="verbatim,quotes",role="primary"]
317
- ----
318
- final Long[] ids = new Long[] {1L, 2L};
319
-
320
- SqlTypeValue value = new AbstractSqlTypeValue() {
321
- protected Object createTypeValue(Connection conn, int sqlType, String typeName) throws SQLException {
322
- ArrayDescriptor arrayDescriptor = new ArrayDescriptor(typeName, conn);
323
- ARRAY idArray = new ARRAY(arrayDescriptor, conn, ids);
324
- return idArray;
325
- }
326
- };
327
- ----
328
-
329
- Kotlin::
330
- +
331
- [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
332
- ----
333
- class TestItemStoredProcedure(dataSource: DataSource) : StoredProcedure() {
334
-
335
- init {
336
- val ids = arrayOf(1L, 2L)
337
- val value = object : AbstractSqlTypeValue() {
338
- override fun createTypeValue(conn: Connection, sqlType: Int, typeName: String?): Any {
339
- val arrayDescriptor = ArrayDescriptor(typeName, conn)
340
- return ARRAY(arrayDescriptor, conn, ids)
341
- }
342
- }
343
- }
344
- }
345
- ----
346
- ======
347
-
229
+ procedure. Oracle has an `createOracleArray` method on `OracleConnection` that you can
230
+ access by unwrapping it. You can use the `SqlTypeValue` to create an array and populate
231
+ it with values from the Java `java.sql.Array`, as the following example shows:
348
232
233
+ include-code::./SqlTypeValueFactory[tag=oracle-array,indent=0]
349
234
0 commit comments