API Differences Between node-oracledb and mle-js-oracledb
There are several differences between node-oracledb
and
mle-js-oracledb
, including the methods for handling connection
management and type mapping.
See Also:
Server-Side JavaScript API Documentation for more information about JavaScript built-in modules
Topics
- Synchronous API and Error Handling
Compared tonode-oracledb
, themle-js-oracledb
driver operates in a synchronous mode, throwing exceptions as they happen. If an asynchronous behavior is desired, calls tomle-js-oracledb
can be wrapped into async functions. - Connection Handling
The method of connection handling with the MLE JavaScript driver is described. - Transaction Management
With respect to transaction management, server-side MLE JavaScript code behaves exactly like PL/SQL procedures and functions. - Type Mapping
The MLE JavaScript driver adheres to the behavior ofnode-oracledb
with respect to conversions between PL/SQL types and JavaScript types. - Unsupported Data Types
The MLE JavaScript driver does not currently support these data types: - Miscellaneous Features Not Available with the MLE JavaScript SQL Driver
Differences between what features are available with the MLE JavaScript driver and withnode-oracledb
are described.
Synchronous API and Error Handling
node-oracledb
, the
mle-js-oracledb
driver operates in a synchronous mode, throwing
exceptions as they happen. If an asynchronous behavior is desired, calls to
mle-js-oracledb
can be wrapped into async functions.
During synchronous operations, API calls block until either a result or an error are
returned. Errors caused by SQL execution are reported as JavaScript exceptions,
otherwise they return the same properties as the node-oracledb
Error
object.
connection.execute
connection.executeMany
connection.getStatementInfo
connection.getSodaDatabase
connection.commit
connection.rollback
resultset.close
resultset.getRow
resultset.getRows
connection.break
node-oracledb
provides a LOB (Large Object) class to
provide streaming access to LOB types. The LOB class implements the asynchronous Node.js
Stream API and cannot be supported in the synchronous MLE JavaScript environment. Large objects are supported using an alternative
API in the MLE JavaScript driver. For these
reasons, the following LOB-related functionality is not supported.
connection.createLob
property oracledb.lobPrefetchSize
constant oracledb.BLOB
constant oracledb.CLOB
node-oracledb
also implements asynchronous streaming of
query results, another feature that's based on the Node.js Stream API. A streaming API
cannot be represented in a synchronous interface as used by the MLE JavaScript driver, therefore the following
functionality is not available.
connection.queryStream()
resultSet.toQueryStream()
Connection Handling
All SQL statements that are executed via the server-side MLE JavaScript driver are executed in the current
session that is running the JavaScript program. SQL statements are executed with the
privileges of the user on whose behalf JavaScript code is executed. As in the
node-oracledb
API, JavaScript code using the MLE JavaScript driver must acquire a Connection
object to execute SQL statements. However, the only connection available is the implicit
connection to the current database session.
JavaScript code must acquire a connection to the current session using the
MLE-specific
oracledb.defaultConnection()
method. On each invocation, it returns
a connection object that represents the session connection. Creation of connections with
the oracledb.createConnection
method of node-oracledb
is not supported by the MLE JavaScript driver;
neither is the creation of a connection pool supported. Connection objects are
implicitly closed and so the call to connection.close()
is not
available with the MLE JavaScript driver.
There is also no statement cursor caching with the MLE JavaScript driver and therefore there is no
stmtCacheSize
property.
The Real Application Cluster (RAC) option offers additional features, designed to increase availability of applications. These include Fast Application Notification (FAN) and Runtime Load Balancing (RLB), neither of which are supported by the MLE JavaScript driver.
Transaction Management
A JavaScript program is executed in the current transaction context of the calling
SQL or PL/SQL statement. An ongoing transaction can be controlled by executing
COMMIT
, SAVEPOINT
, or ROLLBACK
commands. Alternatively, the methods connection.commit()
and
connection.rollback()
can be used.
MLE JavaScript SQL driver connections
cannot be explicitly closed. Applications relying on node-oracledb
behavior where closing a connection performs a rollback of the transaction will need
adjusting. The MLE JavaScript SQL driver neither
performs implicit commit nor rollback of transactions.
The node-oracledb
driver features an auto-commit flag,
defaulting to false. The MLE JavaScript SQL
driver does not implement this feature. If specified, the
connection.execute()
function ignores the parameter.
Type Mapping
node-oracledb
with respect to conversions
between PL/SQL types and JavaScript types.
By default, PL/SQL types map to native JavaScript types (except for BLOBs and CLOBs). Values fetched from query results are implicitly converted. See MLE Type Conversions for more details about MLE type mappings.
As with node-oracledb
, the conversion from non-character data types and
vice versa is directly impacted by the NLS session parameters. The MLE runtime locale has no impact on these
conversions.
oracledb.ORACLE_NUMBER
oracledb.ORACLE_CLOB
oracledb.ORACLE_BLOB
oracledb.ORACLE_TIMESTAMP
oracledb.ORACLE_TIMESTAMP_TZ
oracledb.ORACLE_DATE
oracledb.ORACLE_INTERVAL_YM
oracledb.ORACLE_INTERVAL_DS
As with node-oracledb
, the default mapping to JavaScript types may be
overridden on a case-by-case basis using the fetchInfo
property on
connection.execute()
. Type constants like
oracledb.ORACLE_NUMBER
may be used to override the type mapping for
a specific NUMBER
column in order to avoid implicit conversion and loss
of precision.
Additionally, the JavaScript MLE SQL
driver provides a way to change the default mapping of PL/SQL types globally. If the
oracledb.fetchAsPlsqlWrapper
property contains the corresponding
type constant, Oracle values are fetched as SQL wrapper types previously described. As
with the existing property oracledb.fetchAsString
, this behavior can be
overridden using fetchInfo
and oracledb.DEFAULT
.
Because MLE JavaScript does not support a
Buffer
class, and instead uses Uint8Array
,
property oracledb.fetchAsBuffer
from node-oracledb
does not exist in mle-js-oracledb
, which instead uses
oracledb.fetchAsUint8Array
.
- Oracle values are mainly moved between queries and DML statements, so that the type conversions between PL/SQL and JavaScript types are an unnecessary overhead.
- It is crucial to avoid data loss.
Example 7-19 Using JavaScript Native Data Types vs Using Wrapper Types
This example demonstrates the effect of using JavaScript native data types for calculations. It also compares the loss of precision using JavaScript native types versus using wrapper types.
CREATE OR REPLACE MLE MODULE js_v_wrapper_mod
LANGUAGE JAVASCRIPT AS
/**
*There is a potential loss of precision when using native
*JavaScript types to perform certain calculations. This
*is caused by the underlying implementation as a floating
*point number
*/
export function precisionLoss(){
let summand1 = session
.execute(`SELECT 0.1 summand1`)
.rows[0].SUMMAND1;
let summand2 = session
.execute(`SELECT 0.2 summand2`)
.rows[0].SUMMAND2;
const result = summand1 + summand2;
console.log(`precisionLoss() result: ${result}`);
}
/**
*Use an Oracle data type to preserve precision. The above
*example can be rewritten using the OracleNumber type as
*follows
*/
export function preservePrecision(){
//instruct the JavaScript SQL driver to return results as
//Oracle Number. This could have been done for individual
//statements using the fetchInfo property - the global
//change applies to this and all future calls
oracledb.fetchAsPlsqlWrapper = [oracledb.NUMBER];
let summand1 = session
.execute(`SELECT 0.1 S1`)
.rows[0].S1;
let summand2 = session
.execute(`SELECT 0.2 S2`)
.rows[0].S2;
const result = summand1 + summand2;
console.log(`preservePrecision() result: ${result}`);
}
/
When executing the above functions, the difference in precision becomes immediately obvious.
precisionLoss() result: 0.30000000000000004
preservePrecsion() result: .3
Rather than setting the global
oracledb.fetchAsPlsqlWrapper
property, it is possible to
override the setting per invocation of connection.execute()
. Example 7-20 shows how precisionPreservedGlobal()
can be
rewritten by setting precision inline.
For information about functions available for use with type
OracleNumber
, see Server-Side JavaScript API
Documentation.
Example 7-20 Overriding the Global oracledb.fetchAsPlsqlWrapper Property
This example extends Example 7-19 by showing how precisionPreservedGlobal()
can be
rewritten by preserving precision inline. It demonstrates that rather than setting
the global oracledb.fetchAsPlsqlWrapper
property, it is possible to
override the setting per invocation of connection.execute()
.
CREATE OR REPLACE PROCEDURE fetch_info_example
AS MLE LANGUAGE JAVASCRIPT
{{
let summand1 = session
.execute(
`SELECT 0.1 S1`,
[],
{
fetchInfo:{
S1:{type: oracledb.ORACLE_NUMBER}
}
}
)
.rows[0].S1;
let summand2 = session
.execute(
`SELECT 0.2 S2`,
[],
{
fetchInfo:{
S2:{type: oracledb.ORACLE_NUMBER}
}
}
)
.rows[0].S2;
const result = summand1 + summand2;
console.log(`
preservePrecision():
summand1: ${summand1}
summand2: ${summand2}
result: ${result}
`);
}};
/
Result:
preservePrecision():
summand1: .1
summand2: .2
result: .3
Unsupported Data Types
LONG
LONG RAW
XMLType
BFILE
REF CURSOR
Miscellaneous Features Not Available with the MLE JavaScript SQL Driver
node-oracledb
are described.
Error handling in the MLE JavaScript driver
relies on the JavaScript exception framework rather than using a callback/promise as
node-oracledb
does. The error thrown by the MLE JavaScript SQL driver is identical to the
Error
object available with node-oracledb
.
Several additional client-side features available in
node-oracledb
are not supported by the server-side MLE environment. The MLE JavaScript driver omits the API for these
features.
- Continuous Query Notification (CQN)
- Advanced Queuing is not supported natively, the PL/SQL API can be used as a workaround
Connection.subscribe()
Connection.unsubscribe()
- All Continuous Query Notification constants in the
oracledb
class - All Subscription constants in the
oracledb
class