@@ -209,140 +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", Types.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
220
can use it to create database-specific objects, such as `java.sql.Struct` instances
262
221
or `java.sql.Array` instances. The following example creates a `java.sql.Struct` instance:
263
222
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
- var item = new Object[] {
276
- testItem.getId(),
277
- testItem.getDescription(),
278
- new java.sql.Date(testItem.getExpirationDate().getTime())
279
- };
280
- return connection.createStruct(typeName, item);
281
- }
282
- };
283
- ----
284
-
285
- Kotlin::
286
- +
287
- [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
288
- ----
289
- val (id, description, expirationDate) = TestItem(123L, "A test item",
290
- SimpleDateFormat("yyyy-M-d").parse("2010-12-31"))
291
-
292
- val value = object : AbstractSqlTypeValue() {
293
- override fun createTypeValue(conn: Connection, sqlType: Int, typeName: String?): Any {
294
- val itemDescriptor = StructDescriptor(typeName, conn)
295
- return STRUCT(itemDescriptor, conn,
296
- arrayOf(id, description, java.sql.Date(expirationDate.time)))
297
- }
298
- }
299
- ----
300
- ======
223
+ include-code::./SqlTypeValueFactory[tag=struct,indent=0]
301
224
302
225
You can now add this `SqlTypeValue` to the `Map` that contains the input parameters for the
303
226
`execute` call of the stored procedure.
304
227
305
228
Another use for the `SqlTypeValue` is passing in an array of values to an Oracle stored
306
- procedure. Oracle has its own internal `ARRAY` class that must be used in this case, and
307
- you can use the `SqlTypeValue` to create an instance of the Oracle `ARRAY` and populate
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
308
231
it with values from the Java `java.sql.Array`, as the following example shows:
309
232
310
- [tabs]
311
- ======
312
- Java::
313
- +
314
- [source,java,indent=0,subs="verbatim,quotes",role="primary"]
315
- ----
316
- final Long[] ids = new Long[] {1L, 2L};
317
-
318
- SqlTypeValue value = new AbstractSqlTypeValue() {
319
- protected Object createTypeValue(Connection conn, int sqlType, String typeName) throws SQLException {
320
- return conn.unwrap(OracleConnection.class).createOracleArray(typeName, ids);
321
- }
322
- };
323
- ----
324
-
325
- Kotlin::
326
- +
327
- [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
328
- ----
329
- class TestItemStoredProcedure(dataSource: DataSource) : StoredProcedure() {
330
-
331
- init {
332
- val ids = arrayOf(1L, 2L)
333
- val value = object : AbstractSqlTypeValue() {
334
- override fun createTypeValue(conn: Connection, sqlType: Int, typeName: String?): Any {
335
- val arrayDescriptor = ArrayDescriptor(typeName, conn)
336
- return ARRAY(arrayDescriptor, conn, ids)
337
- }
338
- }
339
- }
340
- }
341
- ----
342
- ======
343
-
344
- [NOTE]
345
- ====
346
- Use `unwrap(OracleConnection.class)` method if connection is not an OracleConnection's instance
347
- ====
233
+ include-code::./SqlTypeValueFactory[tag=oracle-array,indent=0]
348
234
0 commit comments