[{"data":1,"prerenderedAt":63},["ShallowReactive",2],{"integration-node-red-contrib-oracledb-mod\u002F":3},{"_id":4,"categories":5,"author":9,"description":11,"npmOwners":12,"npmScope":14,"name":4,"ffCertified":15,"downloads":16,"version":18,"updatedAt":19,"maintainers":20,"homepage":23,"bugs":24,"repository":26,"time":29,"lastUpdated":19,"created":30,"license":53,"githubOwner":54,"githubRepo":4,"examples":55,"readme":62},"node-red-contrib-oracledb-mod",[6,7,8],"catalogue_database","catalogue_storage","catalogue",{"name":10},"Original Author: Ab Reitsma, Mod-version Maintainer: Vinay Tulluru","Node-RED oracle database nodes",[13],"vtulluru3",null,false,{"week":17},2930,"0.8.0","2026-05-11T06:55:14.174Z",[21],{"name":13,"email":22},"admin@vtulluru.com","https:\u002F\u002Fgithub.com\u002Fvtulluru\u002Fnode-red-contrib-oracledb-mod#readme",{"url":25},"https:\u002F\u002Fgithub.com\u002Fvtulluru\u002Fnode-red-contrib-oracledb-mod\u002Fissues",{"type":27,"url":28},"git","git+https:\u002F\u002Fgithub.com\u002Fvtulluru\u002Fnode-red-contrib-oracledb-mod.git",{"created":30,"modified":19,"0.5.2":31,"0.5.3":32,"0.5.4":33,"0.5.5":34,"0.5.6":35,"0.5.7":36,"0.5.8":37,"0.6.0":38,"0.6.1":39,"0.6.2":40,"0.6.3":41,"0.6.4":42,"0.6.5":43,"0.6.6":44,"0.7.0":45,"0.7.1":46,"0.7.2":47,"0.7.3":48,"0.7.4":49,"0.7.5":50,"0.7.6":51,"0.8.0":52},"2019-02-04T07:02:27.909Z","2019-02-04T07:02:28.221Z","2019-03-13T04:08:24.325Z","2019-03-13T04:17:39.014Z","2019-10-01T02:26:40.205Z","2020-03-15T23:00:16.091Z","2020-05-12T00:13:20.671Z","2020-05-12T01:06:27.886Z","2021-02-24T08:39:10.555Z","2021-03-04T03:02:20.960Z","2022-06-29T07:59:05.959Z","2022-12-11T21:15:06.075Z","2023-12-15T21:32:12.462Z","2024-01-03T18:05:18.030Z","2025-06-15T05:56:01.502Z","2025-06-17T06:41:10.819Z","2025-06-17T07:03:49.634Z","2025-06-17T14:36:56.270Z","2025-06-20T04:22:12.687Z","2025-06-20T06:50:27.450Z","2025-08-05T07:18:30.018Z","2025-10-24T14:34:33.744Z","2026-05-11T06:55:14.064Z","MIT","vtulluru",[56],{"name":57,"path":58,"url":59,"downloadUrl":60,"flow":61},"stored-procedure-example","examples\u002Fstored-procedure-example.json","https:\u002F\u002Fgithub.com\u002Fvtulluru\u002Fnode-red-contrib-oracledb-mod\u002Fblob\u002Fmaster\u002Fexamples\u002Fstored-procedure-example.json","https:\u002F\u002Fraw.githubusercontent.com\u002Fvtulluru\u002Fnode-red-contrib-oracledb-mod\u002Fmaster\u002Fexamples\u002Fstored-procedure-example.json","[{\"id\":\"a1b2c3d4.e5f6g7\",\"type\":\"comment\",\"z\":\"5a6b7c8d.9e0f12\",\"name\":\"How to Call a Stored Procedure\",\"info\":\"This example demonstrates how to call an Oracle stored procedure or function that has OUT parameters.\\n\\nThe key is to use `msg.bindVars` to define the direction and type of each parameter.\",\"x\":230,\"y\":220,\"wires\":[]},{\"id\":\"1a2b3c4d.5e6f78\",\"type\":\"inject\",\"z\":\"5a6b7c8d.9e0f12\",\"name\":\"Trigger with Input Value\",\"props\":[{\"p\":\"payload\"}],\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"{\\\"inputValue\\\":\\\"TEST_VALUE\\\"}\",\"payloadType\":\"json\",\"x\":220,\"y\":280,\"wires\":[[\"9d8c7b6a.5f4e32\"]]},{\"id\":\"9d8c7b6a.5f4e32\",\"type\":\"function\",\"z\":\"5a6b7c8d.9e0f12\",\"name\":\"Prepare msg.bindVars\",\"func\":\"\u002F\u002F 1. Define the PL\u002FSQL block to execute.\\nmsg.query = \\\"BEGIN :output := example_function(input_param =\\u003e :input_param); END;\\\";\\n\\n\u002F\u002F 2. Define the bind variables with direction and type.\\n\u002F\u002F The keys ('output', 'input_param') must match the names in the query.\\nmsg.bindVars = {\\n    output: { dir: \\\"BIND_OUT\\\", type: \\\"STRING\\\", maxSize: 2000 },\\n    input_param: { dir: \\\"BIND_IN\\\", type: \\\"STRING\\\", val: msg.payload.inputValue }\\n};\\n\\nreturn msg;\",\"outputs\":1,\"timeout\":0,\"noerr\":0,\"initialize\":\"\",\"finalize\":\"\",\"libs\":[],\"x\":450,\"y\":280,\"wires\":[[\"e5f4d3c2.1a0b1c\"]]},{\"id\":\"e5f4d3c2.1a0b1c\",\"type\":\"oracledb\",\"z\":\"5a6b7c8d.9e0f12\",\"server\":\"\",\"name\":\"Execute Function\",\"usequery\":false,\"query\":\"\",\"usemappings\":false,\"mappings\":\"[]\",\"resultaction\":\"single-meta\",\"resultlimit\":\"100\",\"x\":670,\"y\":280,\"wires\":[[\"f1e2d3c4.b5a678\"]]},{\"id\":\"f1e2d3c4.b5a678\",\"type\":\"debug\",\"z\":\"5a6b7c8d.9e0f12\",\"name\":\"Display OUT Binds\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload.outBinds\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":880,\"y\":280,\"wires\":[]},{\"id\":\"h8i9j0k1.l2m3n4\",\"type\":\"comment\",\"z\":\"5a6b7c8d.9e0f12\",\"name\":\"IMPORTANT\",\"info\":\"1. Select your oracle-server configuration in the \\\"Execute Function\\\" node.\\n\\n2. Set the Action to \\\"send single message with metadata\\\" to get the `outBinds` in the result.\",\"x\":670,\"y\":220,\"wires\":[]}]","\u003Cp>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fvtulluru\u002Fnode-red-contrib-oracledb-mod\u002Factions\u002Fworkflows\u002Fnpm-publish.yml\">\u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fvtulluru\u002Fnode-red-contrib-oracledb-mod\u002Factions\u002Fworkflows\u002Fnpm-publish.yml\u002Fbadge.svg\" alt=\"Node.js Package\" \u002F>\u003C\u002Fa>\u003C\u002Fp>\n\u003Ch1 id=\"node-red-contrib-oracledb-mod\">\u003Ca class=\"header-anchor\" href=\"#node-red-contrib-oracledb-mod\">node-red-contrib-oracledb-mod\u003C\u002Fa>\u003C\u002Fh1>\n\u003Cp>Robust, modern, and easy-to-use Node-RED nodes for interacting with Oracle Database.\u003C\u002Fp>\n\u003Cp>This module provides a stable connection to Oracle, supporting queries, DML, stored procedures, and advanced data binding, all handled through a resilient connection pool.\u003C\u002Fp>\n\u003Chr \u002F>\n\u003Ch2 id=\"whats-new-in-080\">\u003Ca class=\"header-anchor\" href=\"#whats-new-in-080\">What's new in 0.8.0\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cstrong>Thin mode is now the default\u003C\u002Fstrong> — no Oracle Instant Client install required for most users (Oracle 12.1+, Autonomous Database, wallets all work). Existing configs that had an Instant Client path keep running in thick mode for backwards compatibility, with a one-time migration warning.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>First-class wallet \u002F Autonomous Database support\u003C\u002Fstrong> — Wallet \u002F TNS_ADMIN, Wallet Location, Wallet Password are now config fields. TNS_ADMIN env var is auto-detected and pre-fills the dialog.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>TNS Name dropdown\u003C\u002Fstrong> — aliases are parsed from your wallet's \u003Ccode>tnsnames.ora\u003C\u002Fcode> and offered as a combo box.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Test Connection button\u003C\u002Fstrong> — one-click verification with rich output (server host, service, database, user, current schema, accessible schemas, wallet aliases, connect + total timing).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Pool Stats panel\u003C\u002Fstrong> — live \u003Ccode>connectionsInUse \u002F connectionsOpen\u003C\u002Fcode>, queue length, \u003Cstrong>peak in-use\u003C\u002Fstrong> and \u003Cstrong>peak queued\u003C\u002Fstrong> high-water marks since the pool started. Refreshes every 2 s while open and surfaces sizing hints (e.g. \"consider raising Max Connections\" when peak hits \u003Ccode>poolMax\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Pool-pressure visibility\u003C\u002Fstrong> — query nodes show \u003Ccode>waiting for pool slot... (4\u002F4)\u003C\u002Fcode> when \u003Ccode>getConnection()\u003C\u002Fcode> blocks; NJS-040 errors now read \u003Ccode>pool exhausted: 4\u002F4 in use, 3 queued, waited 60000ms\u003C\u002Fcode> instead of the bare timeout.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>executeMany batch mode\u003C\u002Fstrong> — insert thousands of rows per round-trip via a new \"Batch mode\" checkbox or \u003Ccode>msg.executeMany = true\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Automatic retry on transient errors\u003C\u002Fstrong> — NJS-003\u002F040, ORA-03113\u002F03114\u002F12170\u002F12541\u002F12537\u002F12514 are retried with exponential backoff. Tunable per server config.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Richer pool tuning\u003C\u002Fstrong> — \u003Ccode>poolIncrement\u003C\u002Fcode>, \u003Ccode>queueTimeout\u003C\u002Fcode>, \u003Ccode>stmtCacheSize\u003C\u002Fcode> exposed in the UI.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>\u003Ccode>msg.oracle\u003C\u002Fcode> stats sidecar\u003C\u002Fstrong> — every result message carries \u003Ccode>{ durationMs, mode, rows, rowsAffected }\u003C\u002Fcode>. Streamed (multi) results also include \u003Ccode>chunkIndex\u003C\u002Fcode> \u002F \u003Ccode>totalRowsSoFar\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Node status badges\u003C\u002Fstrong> — successful queries briefly show \u003Ccode>N rows · 23ms\u003C\u002Fcode>; errors stay red for 5s.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Engines bumped to Node ≥ 18\u003C\u002Fstrong>. CI now runs the full test suite on Node 18\u002F20\u002F22 before publish.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Chr \u002F>\n\u003Ch2 id=\"driver-modes-thin-vs-thick\">\u003Ca class=\"header-anchor\" href=\"#driver-modes-thin-vs-thick\">Driver Modes (Thin vs Thick)\u003C\u002Fa>\u003C\u002Fh2>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Use case\u003C\u002Fth>\n\u003Cth>Mode\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Oracle 12.1+, including Autonomous Database\u003C\u002Ftd>\n\u003Ctd>\u003Cstrong>Thin\u003C\u002Fstrong> (default) — no install needed\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Oracle 11g servers\u003C\u002Ftd>\n\u003Ctd>\u003Cstrong>Thick\u003C\u002Fstrong>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Advanced Queuing (AQ), Continuous Query Notification (CQN), sharding\u003C\u002Ftd>\n\u003Ctd>\u003Cstrong>Thick\u003C\u002Fstrong>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Switch via the \u003Cstrong>Driver Mode\u003C\u002Fstrong> dropdown in the oracle-server config. Only one mode can be active per Node-RED process, and switching from thin → thick requires a process restart.\u003C\u002Fp>\n\u003Ch2 id=\"wallet-autonomous-database\">\u003Ca class=\"header-anchor\" href=\"#wallet-autonomous-database\">Wallet \u002F Autonomous Database\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>For OCI Autonomous Database:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Download the wallet zip from the OCI console.\u003C\u002Fli>\n\u003Cli>Unzip it on the host (e.g. \u003Ccode>\u002Fopt\u002Foracle\u002Fnetwork\u002Fadmin\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>In the config node, set \u003Cstrong>TNS_ADMIN\u003C\u002Fstrong> to that directory — or just set the \u003Ccode>TNS_ADMIN\u003C\u002Fcode> environment variable and leave the field blank; the dialog auto-detects it.\u003C\u002Fli>\n\u003Cli>The \u003Cstrong>TNS Name\u003C\u002Fstrong> dropdown will populate from the wallet's \u003Ccode>tnsnames.ora\u003C\u002Fcode>. Pick one (e.g. \u003Ccode>mydb_high\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>Fill \u003Cstrong>User\u003C\u002Fstrong> + \u003Cstrong>Password\u003C\u002Fstrong> on the Security tab. If your wallet is the standard ADB wallet with an SSO file, leave \u003Cstrong>Wallet Password\u003C\u002Fstrong> blank.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>Click \u003Cstrong>Test Connection\u003C\u002Fstrong> to verify before deploying.\u003C\u002Fp>\n\u003Ch2 id=\"connection-pool-tuning\">\u003Ca class=\"header-anchor\" href=\"#connection-pool-tuning\">Connection Pool Tuning\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>All settings are on the Connection tab of the oracle-server config:\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Field\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>What it does\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Min \u002F Max Connections\u003C\u002Ftd>\n\u003Ctd>0 \u002F 4\u003C\u002Ftd>\n\u003Ctd>Pool bounds\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Pool Increment\u003C\u002Ftd>\n\u003Ctd>1\u003C\u002Ftd>\n\u003Ctd>New connections opened when pool grows\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Idle Timeout (s)\u003C\u002Ftd>\n\u003Ctd>60\u003C\u002Ftd>\n\u003Ctd>Idle connection lifetime\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Queue Timeout (ms)\u003C\u002Ftd>\n\u003Ctd>60000\u003C\u002Ftd>\n\u003Ctd>How long a query waits for a free connection before failing with NJS-040\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Stmt Cache Size\u003C\u002Ftd>\n\u003Ctd>30\u003C\u002Ftd>\n\u003Ctd>Prepared statements cached per connection\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch2 id=\"retry-on-transient-errors\">\u003Ca class=\"header-anchor\" href=\"#retry-on-transient-errors\">Retry on Transient Errors\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>The node automatically retries failed \u003Ccode>getConnection\u003C\u002Fcode> \u002F \u003Ccode>execute\u003C\u002Fcode> calls when the error is transient (network blip, ADB warming up, listener restart). Configurable per server config:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Max Retries\u003C\u002Fstrong> (default 3, set 0 to disable)\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Initial Delay (ms)\u003C\u002Fstrong> (default 1000) — doubled each attempt, capped at 10s\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Errors that are \u003Cem>not\u003C\u002Fem> retried (syntax, permissions, ORA-01017, etc.) surface immediately.\u003C\u002Fp>\n\u003Ch2 id=\"batch-mode-executemany\">\u003Ca class=\"header-anchor\" href=\"#batch-mode-executemany\">Batch Mode (executeMany)\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>For high-volume inserts\u002Fupdates, enable \u003Cstrong>Batch mode\u003C\u002Fstrong> on the oracledb (query) node and send an array payload:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-js\">msg.payload = [\n  { id: 1, name: \"alice\" },\n  { id: 2, name: \"bob\" },\n  \u002F\u002F ... thousands of rows\n];\n\u002F\u002F query: INSERT INTO t (id, name) VALUES (:id, :name)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The node returns one message with \u003Ccode>msg.payload = { rowsAffected, outBinds, batchErrors }\u003C\u002Fcode>. You can also enable batch mode dynamically via \u003Ccode>msg.executeMany = true\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"msgoracle-stats-sidecar\">\u003Ca class=\"header-anchor\" href=\"#msgoracle-stats-sidecar\">msg.oracle stats sidecar\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Every successful result message carries a metadata sidecar that doesn't disturb \u003Ccode>msg.payload\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-js\">msg.oracle = {\n  durationMs: 23,\n  mode: \"single\",            \u002F\u002F or \"multi\" | \"single-meta\" | \"batch\" | \"none\"\n  statementKind: \"query\",    \u002F\u002F \"query\" | \"ddl\" | \"plsql\" | \"insert\" | \"update\" | \"delete\" | ...\n  rows: 1,                   \u002F\u002F when applicable\n  rowsAffected: 5            \u002F\u002F when applicable (DML, executeMany)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>For streamed \u003Ccode>multi\u003C\u002Fcode> results, each chunk message also gets \u003Ccode>chunkIndex\u003C\u002Fcode> and \u003Ccode>totalRowsSoFar\u003C\u002Fcode> so downstream nodes can detect \"last chunk\". DDL statements (\u003Ccode>CREATE\u003C\u002Fcode>\u002F\u003Ccode>DROP\u003C\u002Fcode>\u002F\u003Ccode>ALTER\u003C\u002Fcode>\u002F...) produce a \u003Ccode>&lt;verb&gt; ok · Xms\u003C\u002Fcode> status badge instead of the ambiguous \u003Ccode>0 affected\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Chr \u002F>\n\u003Ch2 id=\"prerequisites\">\u003Ca class=\"header-anchor\" href=\"#prerequisites\">Prerequisites\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Thin mode users (most people):\u003C\u002Fstrong> no prerequisites — \u003Ccode>npm install\u003C\u002Fcode> is enough. Skip to the Configuration section.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>The rest of this section applies only if you need \u003Cstrong>Thick mode\u003C\u002Fstrong> (Oracle 11g, AQ, CQN, sharding). You \u003Cstrong>must\u003C\u002Fstrong> have the \u003Cstrong>Oracle Instant Client\u003C\u002Fstrong> libraries installed on the same machine that is running Node-RED.\u003C\u002Fp>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Download:\u003C\u002Fstrong> Get the Instant Client \"Basic\" or \"Basic Light\" package for your operating system from the \u003Ca href=\"https:\u002F\u002Fwww.oracle.com\u002Fdatabase\u002Ftechnologies\u002Finstant-client\u002Fdownloads.html\">Oracle Instant Client Downloads Page\u003C\u002Fa>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Install:\u003C\u002Fstrong> Unzip the package to a permanent location on your system (e.g., \u003Ccode>\u002Fopt\u002Foracle\u002Finstantclient_21_13\u003C\u002Fcode> on Linux, \u003Ccode>C:\\oracle\\instantclient_21_13\u003C\u002Fcode> on Windows).\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Configure Environment:\u003C\u002Fstrong> Node.js needs to know where to find these libraries.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cul>\n\u003Cli>\n\u003Cp>\u003Cstrong>Linux:\u003C\u002Fstrong> Add the path to the \u003Ccode>LD_LIBRARY_PATH\u003C\u002Fcode> environment variable.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Windows:\u003C\u002Fstrong> Add the path to the \u003Ccode>PATH\u003C\u002Fcode> system environment variable.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>macOS:\u003C\u002Fstrong> Add the path to the \u003Ccode>DYLD_LIBRARY_PATH\u003C\u002Fcode> environment variable.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Col>\n\u003Cli>In the node's configuration, you must provide the path to this directory in the \u003Cstrong>Instant Client Path\u003C\u002Fstrong> field. \u003Cem>This directly addresses GitHub issue #52.\u003C\u002Fem>\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"installation\">\u003Ca class=\"header-anchor\" href=\"#installation\">Installation\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Install via the Node-RED Palette Manager or run the following command in your Node-RED user directory (typically \u003Ccode>~\u002F.node-red\u003C\u002Fcode>):\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">\nnpm  install  node-red-contrib-oracledb-mod\n\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"features\">\u003Ca class=\"header-anchor\" href=\"#features\">Features\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\n\u003Cp>\u003Cstrong>Resilient Connection Pooling:\u003C\u002Fstrong> Automatically manages a pool of connections to handle idle timeouts, network disconnects, and database restarts, ensuring your flows are always ready.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Execute SQL and PL\u002FSQL:\u003C\u002Fstrong> Run \u003Ccode>SELECT\u003C\u002Fcode>, \u003Ccode>INSERT\u003C\u002Fcode>, \u003Ccode>UPDATE\u003C\u002Fcode>, \u003Ccode>DELETE\u003C\u002Fcode>, and anonymous PL\u002FSQL blocks.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Stored Procedures &amp; Functions:\u003C\u002Fstrong> Full support for calling stored procedures and functions with \u003Ccode>IN\u003C\u002Fcode>, \u003Ccode>OUT\u003C\u002Fcode>, and \u003Ccode>INOUT\u003C\u002Fcode> parameters using \u003Ccode>msg.bindVars\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Flexible Result Handling:\u003C\u002Fstrong> Choose whether to get all rows at once, stream large result sets, or get metadata like the number of rows affected by a DML statement.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Configurable Connections:\u003C\u002Fstrong> Connect using Classic (\u003Ccode>host:port\u002Fdb\u003C\u002Fcode>) or TNS Name, with configurable connection pool settings.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Built-in Examples:\u003C\u002Fstrong> Comes with an importable example flow for calling stored procedures.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"node-usage\">\u003Ca class=\"header-anchor\" href=\"#node-usage\">Node Usage\u003C\u002Fa>\u003C\u002Fh2>\n\u003Ch3 id=\"1-oracle-server-configuration-node\">\u003Ca class=\"header-anchor\" href=\"#1-oracle-server-configuration-node\">1. \u003Ccode>oracle-server\u003C\u002Fcode> (Configuration Node)\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>This node configures the connection to your database. Using the \u003Cstrong>Connection Pool\u003C\u002Fstrong> is highly recommended for all use cases.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\n\u003Cp>\u003Cstrong>Connection Type:\u003C\u002Fstrong> Choose \"Classic\" for host\u002Fport\u002Fdb or \"TNS Name\" for using a \u003Ccode>tnsnames.ora\u003C\u002Fcode> entry.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Instant Client Path:\u003C\u002Fstrong> The local filesystem path to your Oracle Instant Client installation.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Connection Pool:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Min\u002FMax Connections:\u003C\u002Fstrong> Control the size of the connection pool.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Idle Timeout (s):\u003C\u002Fstrong> How long an idle connection can live in the pool before being terminated. This is key to preventing errors from firewalls closing idle connections.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3 id=\"2-oracledb-query-node\">\u003Ca class=\"header-anchor\" href=\"#2-oracledb-query-node\">2. \u003Ccode>oracledb\u003C\u002Fcode> (Query Node)\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>This node executes the query and sends the results.\u003C\u002Fp>\n\u003Ch4 id=\"common-use-cases\">\u003Ca class=\"header-anchor\" href=\"#common-use-cases\">\u003Cstrong>Common Use Cases\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fh4>\n\u003Cp>\u003Cstrong>Use Case 1: Simple \u003Ccode>SELECT\u003C\u002Fcode> Query\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\n\u003Cp>Set \u003Ccode>msg.query\u003C\u002Fcode> to \u003Ccode>SELECT * FROM employees WHERE department_id = :1\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Set \u003Ccode>msg.payload\u003C\u002Fcode> to \u003Ccode>[50]\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Set the \u003Cstrong>Action\u003C\u002Fstrong> to \u003Ccode>send single query result message\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Output:\u003C\u002Fstrong>  \u003Ccode>msg.payload\u003C\u002Fcode> will be an array of employee objects.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Use Case 2: \u003Ccode>INSERT\u003C\u002Fcode> or \u003Ccode>UPDATE\u003C\u002Fcode> and Get Rows Affected\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\n\u003Cp>Set \u003Ccode>msg.query\u003C\u002Fcode> to \u003Ccode>UPDATE employees SET salary = salary * 1.1 WHERE department_id = :1\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Set \u003Ccode>msg.payload\u003C\u002Fcode> to \u003Ccode>[50]\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Set the \u003Cstrong>Action\u003C\u002Fstrong> to \u003Ccode>send single message with metadata\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Output:\u003C\u002Fstrong>  \u003Ccode>msg.payload\u003C\u002Fcode> will be an object like \u003Ccode>{ rowsAffected: 10, ... }\u003C\u002Fcode>. \u003Cem>This addresses GitHub issues #3, #53, and #35.\u003C\u002Fem>\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Use Case 3: Calling a Stored Procedure with an \u003Ccode>OUT\u003C\u002Fcode> Parameter\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\n\u003Cp>Set \u003Ccode>msg.query\u003C\u002Fcode> to \u003Ccode>BEGIN get_employee_name(:emp_id, :emp_name); END;\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Set \u003Ccode>msg.bindVars\u003C\u002Fcode> as shown below.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Set the \u003Cstrong>Action\u003C\u002Fstrong> to \u003Ccode>send single message with metadata\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Output:\u003C\u002Fstrong>  \u003Ccode>msg.payload.outBinds.emp_name\u003C\u002Fcode> will contain the returned name. \u003Cem>This addresses GitHub issue #6 and #34.\u003C\u002Fem>\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cpre>\u003Ccode class=\"language-javascript\">\n\u002F\u002F Example for msg.bindVars\n\nmsg.bindVars = {\n\nemp_id: { dir:  \"BIND_IN\", val:  101, type:  \"NUMBER\" },\n\nemp_name: { dir:  \"BIND_OUT\", type:  \"STRING\" }\n\n};\n\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cblockquote>\n\u003Cp>For a full list of bind parameter types and directions, see the \u003Ca href=\"https:\u002F\u002Fnode-oracledb.readthedocs.io\u002Fen\u002Flatest\u002Fuser_guide\u002Fbind.html\">official node-oracledb documentation\u003C\u002Fa>.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Ch2 id=\"executing-multiple-statements-scripts\">\u003Ca class=\"header-anchor\" href=\"#executing-multiple-statements-scripts\">Executing Multiple Statements (Scripts)\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>The Oracle driver executes one SQL statement or one PL\u002FSQL block at a time. You cannot send a script with multiple statements separated by semicolons (\u003Ccode>;\u003C\u002Fcode>) in a single query. This will result in an \u003Ccode>ORA-00933\u003C\u002Fcode> error.\u003C\u002Fp>\n\u003Cp>There are two recommended ways to run multiple commands:\u003C\u002Fp>\n\u003Ch3 id=\"1-for-transactional-scripts-insert-update-delete\">\u003Ca class=\"header-anchor\" href=\"#1-for-transactional-scripts-insert-update-delete\">1. For Transactional Scripts (INSERT, UPDATE, DELETE)\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The best practice is to wrap your statements in a single PL\u002FSQL \u003Ccode>BEGIN...END;\u003C\u002Fcode> block. This ensures all commands are executed together as a single, atomic transaction.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Example:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">\nBEGIN\n\nUPDATE inventory SET quantity = quantity - 1  WHERE product_id = :p_id;\n\nINSERT INTO order_log (product_id, log_date) VALUES (:p_id, SYSDATE);\n\nEND;\n\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3 id=\"2-for-sequential-queries\">\u003Ca class=\"header-anchor\" href=\"#2-for-sequential-queries\">2. For Sequential Queries\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>If you need to run multiple independent queries, especially \u003Ccode>SELECT\u003C\u002Fcode> statements, the standard Node-RED approach is to chain multiple \u003Ccode>oracledb\u003C\u002Fcode> nodes in your flow.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Example Flow:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>\u003Ccode>Inject\u003C\u002Fcode> → \u003Ccode>[ oracledb (SELECT from table A) ]\u003C\u002Fcode> → \u003Ccode>[ oracledb (SELECT from table B) ]\u003C\u002Fcode> → \u003Ccode>...\u003C\u002Fcode>\u003C\u002Fp>\n\u003Ch2 id=\"troubleshooting\">\u003Ca class=\"header-anchor\" href=\"#troubleshooting\">Troubleshooting\u003C\u002Fa>\u003C\u002Fh2>\n\u003Ch3 id=\"ora-06550-error-with-beginend-blocks\">\u003Ca class=\"header-anchor\" href=\"#ora-06550-error-with-beginend-blocks\">ORA-06550 Error with BEGIN\u002FEND Blocks\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Cstrong>Problem\u003C\u002Fstrong>: \u003Ccode>ORA-06550: line 1, column X: PLS-00103: Encountered the symbol \"END\" when expecting...\u003C\u002Fcode>\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Solution\u003C\u002Fstrong>: Fixed in version 0.7.6+. The module now intelligently detects PL\u002FSQL blocks and preserves their required semicolons.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Examples that now work correctly\u003C\u002Fstrong>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">-- ✅ Simple anonymous PL\u002FSQL block\nBEGIN\n    DBMS_OUTPUT.PUT_LINE('Hello World');\nEND;\n\n-- ✅ PL\u002FSQL block with variables\nDECLARE\n    v_count NUMBER;\nBEGIN\n    SELECT COUNT(*) INTO v_count FROM dual;\n    DBMS_OUTPUT.PUT_LINE('Count: ' || v_count);\nEND;\n\n-- ✅ PL\u002FSQL block with bind variables\nBEGIN\n    :result := 'Success';\nEND;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Cstrong>Best Practices\u003C\u002Fstrong>:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Always include semicolons with PL\u002FSQL blocks: \u003Ccode>BEGIN...END;\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Use \u003Ccode>\"single-meta\"\u003C\u002Fcode> result action for blocks with OUT parameters\u003C\u002Fli>\n\u003Cli>Ensure proper bind variable configuration for IN\u002FOUT parameters\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3 id=\"other-common-issues\">\u003Ca class=\"header-anchor\" href=\"#other-common-issues\">Other Common Issues\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Cstrong>ORA-00933: SQL command not properly ended\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>This affects regular SQL statements, not PL\u002FSQL blocks\u003C\u002Fli>\n\u003Cli>The module automatically handles this for SQL statements\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>ORA-01036: Illegal variable name\u002Fnumber\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Check your bind variable names match those in your query\u003C\u002Fli>\n\u003Cli>Ensure bind variables are properly formatted in \u003Ccode>msg.bindVars\u003C\u002Fcode>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Connection Issues\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Verify Oracle Instant Client is properly installed and configured\u003C\u002Fli>\n\u003Cli>Check connection pool settings in the oracle-server node\u003C\u002Fli>\n\u003Cli>Ensure your Oracle user has necessary privileges\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"whats-new\">\u003Ca class=\"header-anchor\" href=\"#whats-new\">What's New\u003C\u002Fa>\u003C\u002Fh2>\n\u003Ch3 id=\"version-076\">\u003Ca class=\"header-anchor\" href=\"#version-076\">Version 0.7.6\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>\u003Cstrong>Fixed:\u003C\u002Fstrong> Resolved ORA-06550 errors when executing PL\u002FSQL blocks with \u003Ccode>BEGIN...END;\u003C\u002Fcode> statements. The module now intelligently preserves semicolons for PL\u002FSQL blocks while removing them for regular SQL statements. (Fixes \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fvtulluru\u002Fnode-red-contrib-oracledb-mod\u002Fissues\u002F126\">#126\u003C\u002Fa>).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Enhanced:\u003C\u002Fstrong> Added comprehensive test coverage for PL\u002FSQL block execution scenarios.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Documentation:\u003C\u002Fstrong> Added detailed troubleshooting guide for PL\u002FSQL-related issues.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3 id=\"version-075\">\u003Ca class=\"header-anchor\" href=\"#version-075\">Version 0.7.5\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>\u003Cstrong>Fixed:\u003C\u002Fstrong> Corrected a critical startup crash (\u003Ccode>NJS-007\u003C\u002Fcode> error) that occurred when importing flows with a configured connection pool. Flows are now fully portable. (Fixes \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fvtulluru\u002Fnode-red-contrib-oracledb-mod\u002Fissues\u002F90\">#90\u003C\u002Fa>).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3 id=\"version-074\">\u003Ca class=\"header-anchor\" href=\"#version-074\">Version 0.7.4\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>\u003Cstrong>Feature:\u003C\u002Fstrong> Added Smart Named Binding to automatically handle \u003Ccode>msg.payload\u003C\u002Fcode> objects and prevent \u003Ccode>ORA-01036\u003C\u002Fcode> errors.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Feature:\u003C\u002Fstrong> Implemented more intelligent and persistent node status feedback for running queries and errors.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Fixed:\u003C\u002Fstrong> Resolved an upgrade issue where existing \u003Ccode>oracle-server\u003C\u002Fcode> nodes would be marked as invalid.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Fixed:\u003C\u002Fstrong> Corrected a \u003Ccode>type_already_registered\u003C\u002Fcode> startup error by overhauling the build process.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3 id=\"version-073\">\u003Ca class=\"header-anchor\" href=\"#version-073\">Version 0.7.3\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>This is a major stability and modernization release.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\n\u003Cp>\u003Cstrong>Resilient Connections:\u003C\u002Fstrong> The node now uses a robust \u003Cstrong>Connection Pool\u003C\u002Fstrong>, which resolves numerous issues related to idle timeouts, network disconnects, and stale connections.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Added Metadata Result Option:\u003C\u002Fstrong> The \"single-meta\" action has been re-introduced to get the number of \u003Ccode>rowsAffected\u003C\u002Fcode> from DML statements or \u003Ccode>outBinds\u003C\u002Fcode> from procedures.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Improved Error Handling:\u003C\u002Fstrong> The entire backend has been refactored to use modern \u003Ccode>async\u002Fawait\u003C\u002Fcode>, providing clearer error messages and preventing Node-RED crashes.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>UI and Documentation Overhaul:\u003C\u002Fstrong> The configuration UI and help text have been significantly improved for clarity and ease of use.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Modernized Tooling:\u003C\u002Fstrong> The development toolchain has been upgraded to modern standards.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Added Examples:\u003C\u002Fstrong> A built-in example flow for stored procedures is now included.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fvtulluru\u002Fnode-red-contrib-oracledb-mod\u002Fcommits\">View more commits and changelog\u003C\u002Fa>\u003C\u002Fp>\n",1784738655367]