@@ -432,6 +432,15 @@ For installation information, see the [Node-oracledb Installation Instructions][
432
432
- 20.6 [ Binding Multiple Values to a SQL ` WHERE IN ` Clause] ( #sqlwherein )
433
433
- 20.7 [ Binding Column and Table Names in Queries] ( #sqlbindtablename )
434
434
21 . [ Oracle Database Objects and Collections] ( #objects )
435
+ - 21.1 [ Inserting Objects] ( #objectinsert )
436
+ - 21.2 [ Fetching Objects] ( #objectfetch )
437
+ - 21.3 [ PL/SQL Collection Types] ( #plsqlcollections )
438
+ - 21.3.1 [ PL/SQL Collection Associative Arrays (Index-by)] ( #plsqlindexbybinds )
439
+ - 21.3.2 [ PL/SQL Collection VARRAY Types] ( #plsqlvarray )
440
+ - 21.3.3 [ PL/SQL Collection Nested Tables] ( #plsqlnestedtables )
441
+ - 21.4 [ PL/SQL RECORD Types] ( #plsqlrecords )
442
+ - 21.5 [ Inserting or Passing Multiple Objects of the Same Type] ( #objexecmany )
443
+ - 21.6 [ Oracle Database Object Type Limitations] ( #objectlimitations )
435
444
22 . [ Batch Statement Execution with ` executeMany() ` ] ( #batchexecution )
436
445
23 . [ Transaction Management] ( #transactionmgt )
437
446
24 . [ Statement Caching] ( #stmtcache )
@@ -11031,7 +11040,7 @@ multiple hard-coded SQL statements, each with a different ORDER BY.
11031
11040
You can query and insert most Oracle Database objects and collections,
11032
11041
with some [limitations](#objectlimitations).
11033
11042
11034
- ### Inserting Objects
11043
+ ### <a name="objectinsert"></a> 21.1 Inserting Objects
11035
11044
11036
11045
As an example, the Oracle Spatial type [SDO_GEOMETRY][139] can easily
11037
11046
be used in node-oracledb. Describing SDO_GEOMETRY in SQL*Plus shows:
@@ -11174,7 +11183,7 @@ connection.close({drop: true})`](#connectionclose), or restart the
11174
11183
pool. Then ` getDbObjectClass ()` can be called again to get the
11175
11184
updated type information.
11176
11185
11177
- ### Fetching Objects
11186
+ ### <a name="objectfetch"></a> 21.2 Fetching Objects
11178
11187
11179
11188
When objects are fetched, they are represented as a
11180
11189
[DbObject](#dbobjectclass):
@@ -11221,7 +11230,7 @@ For DbObjects representing Oracle collections, methods such as
11221
11230
11222
11231
` ` ` javascript
11223
11232
console .log (o .SDO_ELEM_INFO .getKeys ()); // [ 0, 1, 2 ]
11224
- console .log (o .SDO_ELEM_INFO .getValues ()); // [ 1, 1003, 3 ]
11233
+ console .log (o .SDO_ELEM_INFO .getValues ()); // [ 1, 1003, 3 ]
11225
11234
` ` `
11226
11235
11227
11236
The options [` fetchAsBuffer` ](#propdbfetchasbuffer) and
@@ -11233,117 +11242,13 @@ LOBs will be fetched as [Lob objects](#lobclass). The
11233
11242
the data. Note it is an asynchronous method and requires a round-trip
11234
11243
to the database.
11235
11244
11236
- ### <a name="plsqlrecords "></a> PL/SQL RECORD Types
11245
+ ### <a name="plsqlcollections "></a> 21.3 PL/SQL Collection Types
11237
11246
11238
- PL/SQL RECORDS can be bound for insertion and retrieval. Given the
11239
- PL/SQL package:
11247
+ PL/SQL has three collection types: associative arrays, VARRAY
11248
+ (variable-size arrays), and nested tables. See [Collection
11249
+ Types][150] in the Database PL/SQL Language Reference.
11240
11250
11241
- ` ` ` sql
11242
- CREATE OR REPLACE PACKAGE seachange AS
11243
- TYPE shiptype IS RECORD (shipname VARCHAR2 (40 ), weight NUMBER );
11244
- PROCEDURE biggership (p_in IN shiptype, p_out OUT shiptype);
11245
- END seachange;
11246
-
11247
- CREATE OR REPLACE PACKAGE BODY seachange AS
11248
- PROCEDURE biggership (p_in IN shiptype, p_out OUT shiptype) AS
11249
- BEGIN
11250
- p_out : = p_in;
11251
- p_out .weight := p_out .weight * 2 ;
11252
- END ;
11253
- END seachange;
11254
- ` ` `
11255
-
11256
- You can get a prototype object for the SHIPTYPE record by calling
11257
- ` getDbObjectClass ()` and then create a new object ` vessel` for a ship.
11258
- This can be bound for input when calling the BIGGERSHIP procedure. To
11259
- retrieve a SHIPTYPE record back from the database, pass the prototype
11260
- object class for the output bind ` type` :
11261
-
11262
- ` ` ` javascript
11263
- ShipTypeClass = await connection .getDbObjectClass (" SEACHANGE.SHIPTYPE" );
11264
-
11265
- vessel = new ShipTypeClass ({ SHIPNAME : ' BoatFace' , WEIGHT : 1200 });
11266
-
11267
- binds = {
11268
- inbv: vessel,
11269
- outbv: { type: ShipTypeClass, dir: oracledb .BIND_OUT }
11270
- };
11271
-
11272
- result = await connection .execute (` CALL seachange.biggership(:inbv, :outbv)` , binds);
11273
- console .log (result .outBinds .outbv .SHIPNAME , result .outBinds .outbv .WEIGHT );
11274
- ` ` `
11275
-
11276
- The output shows the increased ship size:
11277
-
11278
- ` ` `
11279
- BoatFace 2400
11280
- ` ` `
11281
-
11282
- See [plsqlrecord.js][147] for a runnable example.
11283
-
11284
- ### <a name="objvarray"></a> Working with VARRAY Types
11285
-
11286
- Given a table with a VARRAY column:
11287
-
11288
- ` ` ` sql
11289
- CREATE TYPE playertype AS OBJECT (
11290
- shirtnumber NUMBER ,
11291
- name VARCHAR2 (20 ));
11292
-
11293
- CREATE TYPE teamtype AS VARRAY (10 ) OF playertype;
11294
-
11295
- CREATE TABLE sports (sportname VARCHAR2 (20 ), team teamtype);
11296
- ` ` `
11297
-
11298
- You can insert values using:
11299
-
11300
- ` ` ` javascript
11301
- TeamTypeClass = await connection .getDbObjectClass (" TEAMTYPE" );
11302
-
11303
- hockeyTeam = new TeamTypeClass (
11304
- [
11305
- {SHIRTNUMBER : 11 , NAME : ' Elizabeth' },
11306
- {SHIRTNUMBER : 22 , NAME : ' Frank' },
11307
- ]
11308
- );
11309
-
11310
- await connection .execute (
11311
- ` INSERT INTO sports (sportname, team) VALUES (:sn, :t)` ,
11312
- {
11313
- sn: " Hockey" ,
11314
- t: hockeyTeam
11315
- });
11316
- ` ` `
11317
-
11318
- Querying the table could be done like:
11319
-
11320
- ` ` ` javascript
11321
- result = await connection .execute (
11322
- ` SELECT sportname, team FROM sports` ,
11323
- [],
11324
- {
11325
- outFormat: oracledb .OUT_FORMAT_OBJECT
11326
- }
11327
- );
11328
- for (row of result .rows ) {
11329
- console .log (" The " + row .SPORTNAME + " team players are:" );
11330
- for (const player of row .TEAM ) {
11331
- console .log (" " + player .NAME );
11332
- }
11333
- }
11334
- ` ` `
11335
-
11336
- The output would be:
11337
-
11338
- ` ` `
11339
- The Hockey team players are:
11340
- Elizabeth
11341
- Frank
11342
- ` ` `
11343
-
11344
- See [selectvarray.js][146] for a runnable example.
11345
-
11346
- ### <a name="plsqlindexbybinds"></a> PL/SQL Collection Associative Arrays (Index-by)
11251
+ #### <a name="plsqlindexbybinds"></a> 21.3.1 PL/SQL Collection Associative Arrays (Index-by)
11347
11252
11348
11253
Arrays of strings and numbers can be bound to PL/SQL IN, IN OUT, and
11349
11254
OUT parameters of PL/SQL INDEX BY associative array types with integer
@@ -11364,6 +11269,7 @@ Given this table and PL/SQL package:
11364
11269
11365
11270
` ` ` sql
11366
11271
DROP TABLE mytab;
11272
+
11367
11273
CREATE TABLE mytab (id NUMBER , numcol NUMBER );
11368
11274
11369
11275
CREATE OR REPLACE PACKAGE mypkg IS
@@ -11496,12 +11402,195 @@ Parameters](#executebindParams) for more information about binding.
11496
11402
11497
11403
See [plsqlarray.js][58] for a runnable example.
11498
11404
11499
- ### Inserting or Passing Multiple Objects of the Same Type
11405
+ #### <a name="plsqlvarray"></a> 21.3.2 PL/SQL Collection VARRAY Types
11406
+
11407
+ Given a table with a VARRAY column:
11408
+
11409
+ ` ` ` sql
11410
+ CREATE TYPE playertype AS OBJECT (
11411
+ shirtnumber NUMBER ,
11412
+ name VARCHAR2 (20 ));
11413
+ /
11414
+
11415
+ CREATE TYPE teamtype AS VARRAY (10 ) OF playertype;
11416
+ /
11417
+
11418
+ CREATE TABLE sports (sportname VARCHAR2 (20 ), team teamtype);
11419
+ ` ` `
11420
+
11421
+ You can insert values using:
11422
+
11423
+ ` ` ` javascript
11424
+ await connection .execute (
11425
+ ` INSERT INTO sports (sportname, team) VALUES (:sn, :t)` ,
11426
+ {
11427
+ sn: " Hockey" ,
11428
+ t:
11429
+ {
11430
+ type: " TEAMTYPE" ,
11431
+ val:
11432
+ [
11433
+ {SHIRTNUMBER : 11 , NAME : ' Georgia' },
11434
+ {SHIRTNUMBER : 22 , NAME : ' Harriet' }
11435
+ ]
11436
+ }
11437
+ }
11438
+ );
11439
+
11440
+ // Alternatively:
11441
+
11442
+ TeamTypeClass = await connection .getDbObjectClass (" TEAMTYPE" );
11443
+
11444
+ hockeyTeam = new TeamTypeClass (
11445
+ [
11446
+ {SHIRTNUMBER : 22 , NAME : ' Elizabeth' },
11447
+ {SHIRTNUMBER : 33 , NAME : ' Frank' },
11448
+ ]
11449
+ );
11450
+
11451
+ await connection .execute (
11452
+ ` INSERT INTO sports (sportname, team) VALUES (:sn, :t)` ,
11453
+ {
11454
+ sn: " Hockey" ,
11455
+ t: hockeyTeam
11456
+ });
11457
+
11458
+ ` ` `
11459
+
11460
+ Querying the table could be done like:
11461
+
11462
+ ` ` ` javascript
11463
+ result = await connection .execute (
11464
+ ` SELECT sportname, team FROM sports` ,
11465
+ [],
11466
+ {
11467
+ outFormat: oracledb .OUT_FORMAT_OBJECT
11468
+ }
11469
+ );
11470
+ for (row of result .rows ) {
11471
+ console .log (" The " + row .SPORTNAME + " team players are:" );
11472
+ for (const player of row .TEAM ) {
11473
+ console .log (" " + player .NAME );
11474
+ }
11475
+ }
11476
+ ` ` `
11477
+
11478
+ The output would be:
11479
+
11480
+ ` ` `
11481
+ The Hockey team players are:
11482
+ Elizabeth
11483
+ Frank
11484
+ ` ` `
11485
+
11486
+ See [selectvarray.js][146] for a runnable example.
11487
+
11488
+ #### <a name="plsqlnestedtables"></a> 21.3.3 PL/SQL Collection Nested Tables
11489
+
11490
+ Given a nested table ` staffList` :
11491
+
11492
+ ` ` ` sql
11493
+ CREATE TABLE bonuses (id NUMBER , name VARCHAR2 (20 ));
11494
+
11495
+ CREATE OR REPLACE PACKAGE personnel AS
11496
+ TYPE staffList IS TABLE OF bonuses% ROWTYPE ;
11497
+ PROCEDURE awardBonuses (goodStaff staffList);
11498
+ END personnel;
11499
+ /
11500
+
11501
+ CREATE OR REPLACE PACKAGE BODY personnel AS
11502
+ PROCEDURE awardBonuses (goodStaff staffList) IS
11503
+ BEGIN
11504
+ FORALL i IN INDICES OF goodStaff
11505
+ INSERT INTO bonuses (id, name) VALUES (goodStaff (i).id , goodStaff (i).name );
11506
+ END ;
11507
+ END ;
11508
+ /
11509
+ ` ` `
11510
+
11511
+ you can call ` awardBonuses ()` like:
11512
+
11513
+ ` ` ` javascript
11514
+ plsql = ` CALL personnel.awardBonuses(:gsbv)` ;
11515
+
11516
+ binds = {
11517
+ gsbv:
11518
+ {
11519
+ type: " PERSONNEL.STAFFLIST" ,
11520
+ val:
11521
+ [
11522
+ {ID : 1 , NAME : ' Chris' },
11523
+ {ID : 2 , NAME : ' Sam' }
11524
+ ]
11525
+ }
11526
+ };
11527
+
11528
+ await connection .execute (plsql, binds);
11529
+ ` ` `
11530
+
11531
+ Similar with other objects, calling
11532
+ [` getDbObjectClass ()` ](#getdbobjectclass) and using a constructor to
11533
+ create a ` DbObject` for binding can also be used.
11534
+
11535
+ ### <a name="plsqlrecords"></a> 21.4 PL/SQL RECORD Types
11536
+
11537
+ PL/SQL RECORDS can be bound for insertion and retrieval. This example
11538
+ uses the PL/SQL package:
11539
+
11540
+ ` ` ` sql
11541
+ CREATE OR REPLACE PACKAGE seachange AS
11542
+ TYPE shiptype IS RECORD (shipname VARCHAR2 (40 ), weight NUMBER );
11543
+ PROCEDURE biggership (p_in IN shiptype, p_out OUT shiptype);
11544
+ END seachange;
11545
+ /
11546
+
11547
+ CREATE OR REPLACE PACKAGE BODY seachange AS
11548
+ PROCEDURE biggership (p_in IN shiptype, p_out OUT shiptype) AS
11549
+ BEGIN
11550
+ p_out := p_in;
11551
+ p_out .weight := p_out .weight * 2 ;
11552
+ END ;
11553
+ END seachange;
11554
+ /
11555
+ ` ` `
11556
+
11557
+ Similar to previous examples, you can use a prototype DbObject from
11558
+ ` getdbobjectclass ()` for binding, or pass an Oracle type name.
11559
+
11560
+ Below a prototype object for the SHIPTYPE record is returned from
11561
+ ` getDbObjectClass ()` and then a new object ` vessel` is created for a
11562
+ ship. This is bound for input when calling the BIGGERSHIP procedure.
11563
+ To retrieve a SHIPTYPE record back from the the PL/SQL, the prototype
11564
+ object class is passed for the output bind ` type` :
11565
+
11566
+ ` ` ` javascript
11567
+ ShipTypeClass = await connection .getDbObjectClass (" SEACHANGE.SHIPTYPE" );
11568
+
11569
+ vessel = new ShipTypeClass ({ SHIPNAME : ' BoatFace' , WEIGHT : 1200 });
11570
+
11571
+ binds = {
11572
+ inbv: vessel,
11573
+ outbv: { type: ShipTypeClass, dir: oracledb .BIND_OUT }
11574
+ };
11575
+
11576
+ result = await connection .execute (` CALL seachange.biggership(:inbv, :outbv)` , binds);
11577
+ console .log (result .outBinds .outbv .SHIPNAME , result .outBinds .outbv .WEIGHT );
11578
+ ` ` `
11579
+
11580
+ The output shows the increased ship size:
11581
+
11582
+ ` ` `
11583
+ BoatFace 2400
11584
+ ` ` `
11585
+
11586
+ See [plsqlrecord.js][147] for a runnable example.
11587
+
11588
+ ### <a name="objexecmany"></a> 21.5 Inserting or Passing Multiple Objects of the Same Type
11500
11589
11501
11590
You can use ` executeMany ()` with objects. See [Binding Objects with
11502
11591
` executeMany ()` ](#executemanyobjects).
11503
11592
11504
- ### <a name="objectlimitations"></a> Oracle Database Object Type Limitations
11593
+ ### <a name="objectlimitations"></a> 21.6 Oracle Database Object Type Limitations
11505
11594
11506
11595
PL/SQL collections and records can only be bound when both Oracle
11507
11596
client libraries and Oracle Database are 12.1, or higher.
@@ -11798,6 +11887,7 @@ CREATE OR REPLACE PACKAGE rectest AS
11798
11887
TYPE rectype IS RECORD (name VARCHAR2 (40 ), pos NUMBER );
11799
11888
PROCEDURE myproc (p_in IN rectype, p_out OUT rectype);
11800
11889
END rectest;
11890
+ /
11801
11891
` ` `
11802
11892
11803
11893
This can be called like:
@@ -13900,3 +13990,4 @@ When upgrading from node-oracledb version 3.1 to version 4.0:
13900
13990
[147]: https://github.com/oracle/node-oracledb/tree/master/examples/plsqlrecord.js
13901
13991
[148]: https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-C4C426FC-FD23-4B2E-8367-FA5F83F3F23A
13902
13992
[149]: https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-4848E6A0-58A7-44FD-8D6D-A033D0CCF9CB
13993
+ [150]: https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-7E9034D5-0D33-43A1-9012-918350FE148C
0 commit comments