{"id":24926547,"url":"https://github.com/yakovenkodenis/node-oracledb-tutorial","last_synced_at":"2025-09-11T12:34:21.213Z","repository":{"id":96291168,"uuid":"77288380","full_name":"yakovenkodenis/node-oracledb-tutorial","owner":"yakovenkodenis","description":"Пример подключения и использования Oracle Database 11g XE в node.js","archived":false,"fork":false,"pushed_at":"2017-01-03T19:02:51.000Z","size":64,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-30T17:48:01.044Z","etag":null,"topics":["database-adapter","node","node-oracledb","nodejs","oracle-11g","oracle-db","tutorial"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yakovenkodenis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-12-24T15:11:28.000Z","updated_at":"2019-08-13T08:41:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"11772d59-4128-4456-96ab-a2417f42cb06","html_url":"https://github.com/yakovenkodenis/node-oracledb-tutorial","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/yakovenkodenis/node-oracledb-tutorial","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yakovenkodenis%2Fnode-oracledb-tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yakovenkodenis%2Fnode-oracledb-tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yakovenkodenis%2Fnode-oracledb-tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yakovenkodenis%2Fnode-oracledb-tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yakovenkodenis","download_url":"https://codeload.github.com/yakovenkodenis/node-oracledb-tutorial/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yakovenkodenis%2Fnode-oracledb-tutorial/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274634221,"owners_count":25321640,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database-adapter","node","node-oracledb","nodejs","oracle-11g","oracle-db","tutorial"],"created_at":"2025-02-02T12:52:37.056Z","updated_at":"2025-09-11T12:34:21.152Z","avatar_url":"https://github.com/yakovenkodenis.png","language":null,"readme":"# Инструкция по работе с Oracle Database XE в среде node.js\n\n------------------\n\n## Требования к программному обеспечению\n\n1. node.js v7+\n2. npm v3+\n3. Oracle Database 11g XE\n\nДанный гайд ориентирован на работу в среде Unix (в частности, ОС Ubuntu).\n\n### Устанавливаем node и npm\n\n```bash\nsudo apt-get update\nsudo apt-get install nodejs\nsudo apt-get install npm\n```\n\n### Проверка корректности установки node и npm\n\nКоманды, приведённые ниже, должны вывести версии установленных пакетов.\n\n```\nnode -v\nnpm -v\n```\n\n### Инициализация проекта\n\nЗдесь `$PROJECT_ROOT` - адрес корневой директории для проекта.\n\n```bash\ncd $PROJECT_ROOT\nnpm init --yes\n```\n\nНиже приведёт пример инициализации проекта в домашней директории ОС Unix:\n\n```bash\ncd ~\nmkdir my_project \u0026\u0026 cd $_\nnpm init --yes\ntouch index.js\n```\n\nДля простоты будем считать, что весь javascript-код, приведённый ниже, находится в файле `index.js`.\n\nДля запуска приложения будет использоваться следующая команда:\n\n```\nnode --harmony index.js\n```\n\n### Устанавливаем драйвер базы данных (версия 1.11.0)\n\n```bash\nnpm install --save oracledb@1.11.0\n```\n\n-----------------\n\n## Подключение к Oracle DB\n\n### Функция подключения к базе данных и выполнения запроса (Promise-based):\n\n```javascript\nconst oracledb = require('oracledb');\n\nconst executePLSQL = (statement, params=[]) =\u003e\n    new Promise((resolve, reject) =\u003e {\n        oracledb.getConnection(\n            {\n                user: process.env.DB_USER,\n                password: process.env.DB_PASSWORD,\n                connectString: process.env.DB_CONNECTION_STRING\n            }\n        ).then(connection =\u003e {\n            return connection.execute(\n                statement, params\n            ).then(result =\u003e {\n                resolve(result);\n                return connection.release();\n            }).catch(err =\u003e {\n                reject(err);\n                return connection.release();\n            })\n        }).catch(err =\u003e reject(err));\n    });\n```\n\nИспользование промисов позволит в дальнейшем использовать синтаксис `async/await` для выполнения запросов. Однако, [официальный драйвер](https://github.com/oracle/node-oracledb) предоставляет не только Promise-based интерфейс, но и callback-based.\n\nОписанная выше функция принимает параметры `statement` и `params`. Параметр `statement` - PL/SQL-запрос, а `params` - параметры, которые необходимо передать в запрос (об этом ниже).\n\nМетод `getConnection` на объекте `oracledb` принимает в качестве параметра объект с конфигурациями подключения (имя пользователя, пароль и адрес для подключения к базе данных). Сами параметры лучше хранить в переменных среды (например, использовать пакет [dotenv](https://github.com/motdotla/dotenv)) и потом получать доступ к ним через `process.env.$PARAM_NAME`, как показано в коде выше.\n\nПример параметра `connectString` для Oracle DB XE, установленной локально со всеми параметрами по умолчанию: `localhost/XE`.\n\nВызов `oracledb.getConnection` вернёт промис, в который будет передан объект `connection`. Объект `connection` позволяет выполнять запросы непосредственно к базе данных (метод `connection.execute`). После выполнения необходимых операций с базой данных, соединение `connection` нужно освобождать, используя метод `connection.release()`.\n\n### Примеры выполнения запросов\n\nДопустим, мы хотим выполнить вызов хранимой процедуры, которая в базе данных была объявлена следующим образом:\n\n```sql\n  procedure buy_book(user_id users.id%type, book_id books.id%type, books_count books.available_count%type) is\n    currently_available_books books.available_count%type;\n    not_enough_books_in_store exception;\n    negative_or_zero_count exception;\n    begin\n      select available_count into currently_available_books from books where id = book_id;\n\n      if currently_available_books - books_count \u003c 0 then\n        raise not_enough_books_in_store;\n      elsif books_count \u003c= 0 then\n        raise negative_or_zero_count;\n      end if;\n      \n      insert into sales values (sales_seq.nextval, sysdate, user_id, book_id, books_count);\n      \n      exception\n        when not_enough_books_in_store then\n          raise_application_error(-20001, 'Not enough books in store');\n        when negative_or_zero_count then\n          raise_application_error(-20002, 'You cannot buy 0 or less books');\n    end buy_book;\n```\n\nДля этого напишем простую функцию, которая будет принимать параметры, необходимые для вызова процедуры (`user_id`, `book_id`, `books_count`), а возвращать будет массив, состоящий из двух элементов: первый элемент - строка с запросом, второй элемент - массив параметров. Тут мы используем массив, потому что далее будет удобно пользоватья spread-оператором при вызове `executePLSQL`.\n\n```javascript\nconst buyBook = (userId, bookId, booksCount) =\u003e [\n    'begin buy_book(:user_id, :book_id, :books_count); end;',\n    [userId, bookId, booksCount]\n];\n```\n\nИмена параметров в строке запроса не имеют значения, важен только их порядок, который должен совпадать с порядком значений в массиве параметров.\n\nИспользовать нашу функцию можно будет следующим образом:\n\nВнутри фукцнии, объявленной как `async`:\n\n```javascript\nconst f = async() =\u003e {\n    const plsqlResult = await executePLSQL(...buyBook(1, 1, 15));\n    console.log(plsqlResult);\n}\n```\n\nИспользуя `.then` на объекте промиса, возвращаемого функцией `executePLSQL`:\n\n```javascript\nexecutePLSQL(...buyBook(1, 1, 15))\n  .then(data =\u003e console.log(data))\n  .catch(err =\u003e console.log(err));\n```\n\nНиже представлен пример выполнения хранимой в бд функции, которая возвращает значение.\n\nПример кода функции в бд:\n\n```sql\n  function get_books_csv_by_publisher(publisher_id in publishers.id%type) return varchar2 as\n    result varchar2(2000);\n    book_name books.name%type;\n    cursor books_cur is select books.name from books where books.publisher_id = publisher_id;\n    begin\n        result := '';\n        open books_cur;\n        loop\n          fetch books_cur into book_name;\n          exit when books_cur%notfound;\n          result := result || book_name || ',';\n        end loop;\n        close books_cur;\n        return result;\n    end get_books_csv_by_publisher;\n```\n\nВ случае, когда нам нужно получить значение, возвращаемое хранимой в бд функцией, `connection.execute` вторым параметром будет принимать объект специального вида, а не массив, как раньше. Объект должен будет содержать поля, обозначающие тип возвращаемого значения, его размер и направление (н-р, BIND_OUT). \n\nДля этого напишем вспомогательную функцию, которая будет принимать массив наших параметров для запроса и тип возвращаемого значения, а возвращать будет объект нужного вида. `zipObject` - функция из пакета [lodash](https://github.com/lodash/lodash).\n\n```javascript\nconst zipObject = require('lodash/zipObject');\n\nconst zipParams = (params, type) =\u003e\n    Object.assign({}, zipObject([...Array(params.length).keys()], params), {\n        result: { dir: oracledb.BIND_OUT, type, maxSize: 2000 }\n    });\n```\n\nТеперь напишем вспомогательную функцию `getBooksCSVbyPublisher` по типу ранее описанной `buyBook`:\n\n```javascript\nconst getBooksCSVbyPublisher = (id) =\u003e [\n    `begin :result := get_books_csv_by_publisher(:0); end;`,\n    zipParams([id], oracledb.STRING)\n];\n```\n\nПримеры использования представлены ниже.\n\nВнутри `async` функции:\n\n```javascript\nconst f = async() =\u003e {\n    try {\n        const dbResponse = await executePLSQL(...getBooksCSVbyPublisher(1));\n        const jsonResponse = JSON.stringify(dbResponse.outBinds.result.slice(0, -1));\n        console.log(jsonResponse);\n    } catch (e) {\n        console.log(e);\n    }\n}\n```\n\nВторой вариант:\n\n```javascript\nexecutePLSQL(...getBooksCSVbyPublisher(1))\n  .then(dbResponse =\u003e {\n        const jsonResponse = JSON.stringify(dbResponse.outBinds.result.slice(0, -1));\n        console.log(jsonResponse);\n  })\n  .catch(err =\u003e console.log(err));\n```\n\n-------------------------\n\nВыше были описаны базовые примеры использования драйвера [node-oracledb](https://github.com/oracle/node-oracledb). Для более продвинутых вариантов использования стоит обращаться к [официальной документации](https://github.com/oracle/node-oracledb/blob/master/doc/api.md).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyakovenkodenis%2Fnode-oracledb-tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyakovenkodenis%2Fnode-oracledb-tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyakovenkodenis%2Fnode-oracledb-tutorial/lists"}