Skip to content

Commit 5848805

Browse files
committed
Documentation, Test and Example updates for 6.6 release
1 parent be408fa commit 5848805

File tree

12 files changed

+398
-22
lines changed

12 files changed

+398
-22
lines changed

doc/src/release_notes.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ node-oracledb `v6.6.0 <https://github.com/oracle/node-oracledb/compare/v6.5.1...
1313
Thin Mode Changes
1414
+++++++++++++++++
1515

16-
#) Added support to use IFILE parameter to embed custom
17-
network configuration files in the main tnsnames.ora file.
16+
#) Added support to use ``IFILE`` parameter to embed custom
17+
network configuration files in the :ref:`tnsnames.ora <tnsadmin>` file.
1818

19-
#) Fixed bug which throws a ``TypeError: objType.attributes is not iterable``
20-
error when :ref:`DbObject Class <dbobjectclass>` instance contains an
21-
attribute of type ``SYS.XMLTYPE``.
19+
#) Fixed bug which throws a ``TypeError: objType.attributes is not iterable``
20+
error when :ref:`DbObject Class <dbobjectclass>` instance contains an
21+
attribute of type ``SYS.XMLTYPE``.
2222

23-
#) Fixed bug which throws an ``NJS-130`` error when calling
24-
:meth:`connection.getDbObjectClass()` with an object type name containing
25-
``%ROWTYPE``.
23+
#) Fixed bug which throws an ``NJS-130`` error when calling
24+
:meth:`connection.getDbObjectClass()` with an object type name containing
25+
``%ROWTYPE``.
2626

2727
#) Fixed bug which throws an ``NJS-112`` error during fetching of JSON and
2828
vector columns after table recreation. This fix is similar to the one

doc/src/user_guide/bind.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,6 @@ This PL/SQL procedure can be called in node-oracledb using:
489489
cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
490490
},
491491
{
492-
prefetchRows: 1000, // tune the internal getRow() data fetch performance
493492
fetchArraySize: 1000
494493
}
495494
);
@@ -515,7 +514,6 @@ number of rows:
515514
cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
516515
},
517516
{
518-
prefetchRows: 200, // tune the getRows() call
519517
fetchArraySize: 200
520518
}
521519
);

doc/src/user_guide/initialization.rst

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ files affect connections and applications. The common files are:
344344
- Description
345345
* - ``tnsnames.ora``
346346
- Contains Oracle Net Service names and Oracle Net options for databases that can be connected to, see :ref:`Net Service Names for Connection Strings <tnsnames>`. This file is only needed for advanced configuration. Not needed if connection strings use the :ref:`Easy Connect syntax <easyconnect>`. The `Oracle Net documentation on tnsnames.ora <https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-7F967CE5-5498-427C-9390-4A5C6767ADAA>`__ has more information.
347+
348+
From version 6.6 onwards, node-oracledb recognizes the `IFILE <https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-F8AC6FC6-F456-481F-8997-3B0E906BB745>`__ parameter that is used in the ``tnsnames.ora`` file to embed custom network configuration files.
347349
* - ``sqlnet.ora``
348350
- A configuration file controlling the network transport behavior. For example it can set call timeouts for :ref:`high availability <connectionha>`, or be used to :ref:`encrypt network traffic <securenetwork>`, or be used to configure logging and tracing. The `Oracle Net documentation on sqlnet.ora <https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-19423B71-3F6C-430F-84CC-18145CC2A818>`__ has more information. Many settings can alternatively be specified using :ref:`Easy Connect syntax <easyconnect>`
349351

@@ -502,6 +504,8 @@ explicitly specified or a default location will be used. Do one of:
502504
installation, in ``$ORACLE_HOME/network/admin`` or
503505
``$ORACLE_BASE_HOME/network/admin``.
504506
507+
.. _oratzfile:
508+
505509
Using the Optional Time Zone File
506510
---------------------------------
507511
@@ -527,11 +531,13 @@ time zones. By default the larger ``timezlrg_n.dat`` file is used. If
527531
you want to use the smaller ``timezone_n.dat`` file, then set the
528532
``ORA_TZFILE`` environment variable to the name of the file without any
529533
directory prefix, for example ``export ORA_TZFILE=timezone_32.dat``.
530-
With Oracle Instant Client 12.2 or later, you can also use an external
531-
time zone file. Create a subdirectory ``oracore/zoneinfo`` under the
532-
Instant Client directory, and move the file into it. Then set
533-
``ORA_TZFILE`` to the file name, without any directory prefix. The
534-
``genezi -v`` utility will show the time zone file in use.
534+
From Oracle Instant Client 12.2, you can also use an external time zone
535+
file. Create a subdirectory ``oracore/zoneinfo`` under the Instant Client
536+
directory, and move the file into it. Then set ``ORA_TZFILE`` to the file
537+
name, without any directory prefix. The ``genezi -v`` utility will show
538+
the time zone file in use. With Oracle Instant Client 19.18 (or later), you
539+
can alternatively place the external time zone file in any directory and then
540+
set the ``ORA_TZFILE`` environment variable to the absolute path of the file.
535541
536542
The Oracle Database documentation contains more information about time
537543
zone files, see `Choosing a Time Zone
@@ -575,7 +581,7 @@ like ``LD_LIBRARY_PATH`` must be set before Node.js starts.
575581
* - ``ORA_SDTZ``
576582
- The default session time zone, see :ref:`Fetching Dates and Timestamps <datehandling>`.
577583
* - ``ORA_TZFILE``
578-
- The name of the Oracle time zone file to use. See the notes below.
584+
- The name of the Oracle time zone file to use. See :ref:`oratzfile`.
579585
* - ``ORACLE_HOME``
580586
- The directory containing the Oracle Database software. This directory must be accessible by the Node.js process. This variable should *not* be set if node-oracledb uses Oracle Instant Client.
581587
* - ``NLS_LANG``

doc/src/user_guide/objects.rst

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,71 @@ The output shows the increased ship size:
672672
See `plsqlrecord.js <https://github.com/oracle/node-oracledb/tree/main/
673673
examples/plsqlrecord.js>`__ for a runnable example.
674674

675+
.. _plsqlrecordrowtype:
676+
677+
PL/SQL Records with %ROWTYPE Attribute
678+
--------------------------------------
679+
680+
PL/SQL RECORDS with `%ROWTYPE <https://www.oracle.com/pls/topic/lookup?ctx=
681+
dblatest&id=GUID-4E0B9FE2-909D-444A-9B4A-E0243B7FCB99>`__ attribute can be
682+
bound for insertion and retrieval. This was introduced in node-oracledb 6.6.
683+
The following example uses the PL/SQL package ``MY_PKG`` and table ``STAFF``:
684+
685+
.. code-block:: javascript
686+
687+
const stmts = [
688+
689+
`CREATE TABLE STAFF (ID NUMBER, NAME VARCHAR2(25))`,
690+
691+
`INSERT INTO STAFF VALUES (1, 'ADSA')`,
692+
693+
`CREATE OR REPLACE PACKAGE MY_PKG AS
694+
TYPE STAFF_ARRAY IS TABLE OF STAFF%ROWTYPE
695+
INDEX BY BINARY_INTEGER;
696+
PROCEDURE prGetRecords(out_rec OUT MY_PKG.STAFF_ARRAY);
697+
END MY_PKG;`,
698+
699+
`CREATE OR REPLACE PACKAGE BODY MY_PKG IS
700+
PROCEDURE prGetRecords(out_rec OUT MY_PKG.STAFF_ARRAY)
701+
IS
702+
CURSOR c_STAFF IS
703+
SELECT *
704+
FROM STAFF;
705+
BEGIN
706+
OPEN c_STAFF;
707+
FETCH c_STAFF BULK COLLECT INTO out_rec;
708+
CLOSE c_STAFF;
709+
END prGetRecords;
710+
END MY_PKG;`
711+
];
712+
713+
for (const s of stmts) {
714+
await conn.execute(s);
715+
}
716+
717+
You can pass the Oracle type name ``STAFF_ARRAY`` in the
718+
:meth:`connection.getDbObjectClass()` method. To retrieve a STAFF_ARRAY record
719+
back from the PL/SQL, the prototype object class is passed for the output
720+
``bind`` type:
721+
722+
.. code-block:: javascript
723+
724+
const objClass = await conn.getDbObjectClass("MY_PKG.STAFF_ARRAY");
725+
const result = await conn.execute(`CALL MY_PKG.prGetRecords(:out_rec)`,
726+
{out_rec: {type: objClass, dir: oracledb.BIND_OUT}});
727+
for (const val of result.outBinds.out_rec) {
728+
console.log("\nRow contents:");
729+
console.log(val);
730+
}
731+
732+
This prints the following output::
733+
734+
Row contents:
735+
[HR.STAFF%ROWTYPE] { ID: 1, NAME: 'ADSA' }
736+
737+
See `plsqlrowtype.js <https://github.com/oracle/node-oracledb/tree/main/
738+
examples/plsqlrowtype.js>`__ for a runnable example.
739+
675740
.. _objexecmany:
676741

677742
Inserting or Passing Multiple Objects of the Same Type
@@ -680,6 +745,67 @@ Inserting or Passing Multiple Objects of the Same Type
680745
You can use ``executeMany()`` with objects. See :ref:`Binding Objects with
681746
executeMany() <executemanyobjects>`.
682747

748+
.. _objxmltype:
749+
750+
Using XMLType Data in DbObjects
751+
===============================
752+
753+
From version 6.6 onwards, you can use a :ref:`DbObject Class <dbobjectclass>`
754+
instance with an attribute of type ``SYS.XMLTYPE`` in node-oracledb Thin mode.
755+
756+
Consider the following object ``NODB_XMLTYPE``:
757+
758+
.. code-block:: sql
759+
760+
CREATE TYPE nodb_xmltype AS OBJECT (
761+
XMLDATA sys.xmltype);
762+
763+
The example below defines the XML data and queries this data from the
764+
``NODB_XMLTYPE`` object.
765+
766+
.. code-block:: javascript
767+
768+
const XMLData =
769+
'<Warehouse>\n ' +
770+
'<WarehouseId>1</WarehouseId>\n ' +
771+
'<WarehouseName>Melbourne, Australia</WarehouseName>\n ' +
772+
'<Building>Owned</Building>\n ' +
773+
'<Area>2020</Area>\n ' +
774+
'<Docks>1</Docks>\n ' +
775+
'<DockType>Rear load</DockType>\n ' +
776+
'</Warehouse>\n';
777+
const sql = `SELECT nodb_xmltype(sys.xmltype('${XMLData}')) FROM dual`;
778+
const result = await connection.execute(sql);
779+
console.log('XML Data:\n', result.rows[0][0].XMLDATA);
780+
781+
This query prints the XMLType data in the object ``nodb_xmltype``::
782+
783+
XML Data:
784+
<Warehouse>
785+
<WarehouseId>1</WarehouseId>
786+
<WarehouseName>Melbourne, Australia</WarehouseName>
787+
<Building>Owned</Building>
788+
<Area>2020</Area>
789+
<Docks>1</Docks>
790+
<DockType>Rear load</DockType>
791+
</Warehouse>
792+
793+
To validate the metadata inside the object, you can use:
794+
795+
.. code-block:: javascript
796+
797+
const xmlObjClass = result.metaData[0];
798+
const pInObj = new xmlObjClass.dbTypeClass();
799+
console.log('Data Type:\n', pInObj.attributes.XMLDATA.type);
800+
801+
This prints an output such as::
802+
803+
Data Type:
804+
[DbType DB_TYPE_XMLTYPE]
805+
806+
See `xmltypeInDbObject.js <https://github.com/oracle/node-oracledb/tree/main/
807+
examples/xmltypeInDbObject.js>`__ for a runnable example.
808+
683809
.. _objectlimitations:
684810

685811
Oracle Database Object Type Limitations

examples/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ File Name | Description
106106
[`plsqlproc.js`](plsqlproc.js) | How to call a PL/SQL procedure
107107
[`plsqlrecord.js`](plsqlrecord.js) | Shows binding of PL/SQL RECORDS
108108
[`plsqlvarrayrecord.js`](plsqlvarrayrecord.js) | Shows binding a VARRAY of RECORD in PL/SQL
109+
[`plsqlrowtype.js`](plsqlrowtype.js) | Shows binding of PL/SQL %ROWTYPE object
109110
[`raw.js`](raw.js) | Shows using a Buffer to insert and select a RAW
110111
[`refcursor.js`](refcursor.js) | Shows using a ResultSet to fetch rows from a REF CURSOR
111112
[`refcursortoquerystream.js`](refcursortoquerystream.js) | Converts a REF CURSOR returned from `execute()` to a query stream.
@@ -134,3 +135,4 @@ File Name | Description
134135
[`vectortype2.js`](vectortype2.js) | Insert data into VECTOR columns and verify vector operations.
135136
[`version.js`](version.js) | Shows the node-oracledb version attributes
136137
[`webapp.js`](webapp.js) | A simple web application using a connection pool
138+
[`xmltypeInDbObject.js`](xmltypeInDbObject.js) | Work with XMLType data in DbObject (Thin mode only)

examples/plsqlrowtype.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/* Copyright (c) 2024, Oracle and/or its affiliates. */
2+
3+
/******************************************************************************
4+
*
5+
* This software is dual-licensed to you under the Universal Permissive License
6+
* (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7+
* 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8+
* either license.
9+
*
10+
* If you elect to accept the software under the Apache License, Version 2.0,
11+
* the following applies:
12+
*
13+
* Licensed under the Apache License, Version 2.0 (the "License");
14+
* you may not use this file except in compliance with the License.
15+
* You may obtain a copy of the License at
16+
*
17+
* https://www.apache.org/licenses/LICENSE-2.0
18+
*
19+
* Unless required by applicable law or agreed to in writing, software
20+
* distributed under the License is distributed on an "AS IS" BASIS,
21+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22+
* See the License for the specific language governing permissions and
23+
* limitations under the License.
24+
*
25+
* NAME
26+
* plsqlrowtype.js
27+
*
28+
* DESCRIPTION
29+
* Shows binding of PL/SQL %ROWTYPE
30+
*
31+
*****************************************************************************/
32+
33+
'use strict';
34+
35+
Error.stackTraceLimit = 50;
36+
37+
const oracledb = require('oracledb');
38+
const dbConfig = require('./dbconfig.js');
39+
40+
// This example runs in both node-oracledb Thin and Thick modes.
41+
//
42+
// Optionally run in node-oracledb Thick mode
43+
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
44+
45+
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
46+
// On Windows and macOS Intel you can specify the directory containing the
47+
// libraries at runtime or before Node.js starts. On other platforms (where
48+
// Oracle libraries are available) the system library search path must always
49+
// include the Oracle library path before Node.js starts. If the search path
50+
// is not correct, you will get a DPI-1047 error. See the node-oracledb
51+
// installation documentation.
52+
let clientOpts = {};
53+
// On Windows and macOS Intel platforms, set the environment
54+
// variable NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
55+
if (process.platform === 'win32' || (process.platform === 'darwin' && process.arch === 'x64')) {
56+
clientOpts = { libDir: process.env.NODE_ORACLEDB_CLIENT_LIB_DIR };
57+
}
58+
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
59+
}
60+
61+
console.log(oracledb.thin ? 'Running in thin mode' : 'Running in thick mode');
62+
63+
async function run() {
64+
let conn;
65+
const table = 'STAFF';
66+
const stmts = [
67+
`CREATE TABLE ${table} (ID NUMBER, NAME VARCHAR2(25), AGE NUMBER(3) INVISIBLE)`,
68+
69+
`INSERT INTO ${table} VALUES (1, 'ADSA')`,
70+
71+
`CREATE OR REPLACE PACKAGE FOO_TEST AS
72+
TYPE FOO_TMP_ARRAY IS TABLE OF ${table}%ROWTYPE
73+
INDEX BY BINARY_INTEGER;
74+
PROCEDURE prGetRecords(out_rec OUT FOO_TEST.FOO_TMP_ARRAY);
75+
END FOO_TEST;`,
76+
77+
`CREATE OR REPLACE PACKAGE BODY FOO_TEST IS
78+
PROCEDURE prGetRecords(out_rec OUT FOO_TEST.FOO_TMP_ARRAY)
79+
IS
80+
CURSOR c_${table} IS
81+
SELECT *
82+
FROM ${table};
83+
BEGIN
84+
OPEN c_${table};
85+
FETCH c_${table} BULK COLLECT INTO out_rec;
86+
CLOSE c_${table};
87+
END prGetRecords;
88+
END FOO_TEST;`
89+
];
90+
91+
try {
92+
conn = await oracledb.getConnection(dbConfig);
93+
for (const s of stmts) {
94+
await conn.execute(s);
95+
}
96+
const objClass = await conn.getDbObjectClass("FOO_TEST.FOO_TMP_ARRAY");
97+
const result = await conn.execute(`CALL FOO_TEST.prGetRecords(:out_rec)`, {out_rec: {type: objClass, dir: oracledb.BIND_OUT}});
98+
for (const val of result.outBinds.out_rec) {
99+
console.log("\nRow contents:");
100+
console.log(val);
101+
}
102+
console.log("\nColumn Information:");
103+
console.log(objClass.prototype.elementTypeClass.prototype.attributes);
104+
} catch (err) {
105+
if (err.errorNum != 942)
106+
console.log(err);
107+
} finally {
108+
if (conn) {
109+
await conn.execute(`DROP TABLE ${table} PURGE`);
110+
await conn.close();
111+
}
112+
}
113+
}
114+
115+
run();

0 commit comments

Comments
 (0)