Что необходимо указать в connectString для подключения к базе данных Oracle?
Ситуация следующая: мне необходимо реализовать подключение БД, которая находится на моей локальной машине к Node.js проекту с помощью oracledb.
В процессе изучения удалось дойти до метода getConnect, у которого есть 3 атрибута. С name и password вопросов нет, а вот с connectString вопросы всё-таки возникли.
Что именно требуется указать в connectString ?
Прошу по возможности показать и пример заполнения.
Ответы (2 шт):
const connection = await oracledb.getConnection(
{
user : "user",
password : passwd,
connectString : "dbserver.domain.com:1521/pdb1"
});
Где connectString имеет следующую структуру (подробнее в оф.док.):
dbserver.domain.com - Полное или неполное имя машины, или IP, на которой работает прослушиватель БД (listener). В локальном окружении должна быть возможность разрешения имени в IP. Для локальной машины: localhost или 127.0.0.1.
:1521 - Порт, который сконфигурирован в прослушивателе, по умолчанию 1521.
/pdb1 - имя сервиса, с которым прослушиватель обслуживает запросы на подключение.
Важно: это не имя БД (db_name) и не SID, это имя сервиса (service_name), присвоенное конкретной БД. В течении ~1 мин. после старта БД регистрирует себя на прослушивателе - "посылай ко мне все запросы на подсоединение с этим именем".
В дополнение к принятому ответу.
oracledb - низкоуровневая библиотека и, обычно, в разработке используются более высокоуровневые библиотеки - query builder или orm.
Примеры демонстрируют запрос к таблице DEPARTMENTS схемы HR.
Пример работы oracledb:
const oracledb = require('oracledb');
(async () => {
let connection;
try {
connection = await oracledb.getConnection({
user: 'hr',
password: 'hr_schema_password',
connectString: 'mydbmachine.example.com:1721/orclpdb1'
});
const { rows: items } = await connection.execute(
`SELECT department_id, department_name
FROM hr.departments WHERE department_id > :id`,
[100],
{
outFormat: oracledb.OUT_FORMAT_OBJECT,
maxRows: 2
}
);
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
})();
[
{ DEPARTMENT_ID: 110, DEPARTMENT_NAME: 'Accounting' },
{ DEPARTMENT_ID: 120, DEPARTMENT_NAME: 'Treasury' }
]
Пример с использование SQL query builder knex:
const { default: Knex } = require('knex');
(async () => {
let knex;
try {
knex = await Knex({
client: 'oracledb',
connection: {
user: 'hr',
password: 'hr_schema_password',
connectString: 'mydbmachine.example.com:1721/orclpdb1'
},
wrapIdentifier: (value, origImpl) => origImpl(value.toUpperCase())
});
const qb = knex.queryBuilder()
.table('departments').withSchema('hr')
.where('department_id', '>', 100)
.select(['department_id', 'department_name'])
.limit(2);
const items = await qb.select();
} catch (err) {
console.error(err);
} finally {
if (knex) {
try {
await knex.destroy();
} catch (err) {
console.error(err);
}
}
}
})();
[
{ DEPARTMENT_ID: 110, DEPARTMENT_NAME: 'Accounting' },
{ DEPARTMENT_ID: 120, DEPARTMENT_NAME: 'Treasury' }
]
Пример с использование orm typeormtypeorm:
import 'reflect-metadata';
import { createConnection, Entity, Column, PrimaryColumn, getRepository, MoreThan, JoinColumn, ManyToOne, LessThan } from 'typeorm';
@Entity('DEPARTMENTS')
class Department {
@PrimaryColumn('number')
DEPARTMENT_ID: number;
@Column('varchar', {length: 30})
DEPARTMENT_NAME: string;
@Column('number')
MANAGER_ID: number;
@Column('number')
LOCATION_ID: number;
@ManyToOne((type) => Employee)
@JoinColumn({ name: 'MANAGER_ID' })
MANAGER: Employee;
}
@Entity('EMPLOYEES')
class Employee {
@PrimaryColumn('number')
EMPLOYEE_ID: number;
@Column('varchar', {length: 20})
FIRST_NAME: string;
@Column('varchar', {length: 25})
LAST_NAME: string;
}
(async () => {
const connection = await createConnection({
type: 'oracle',
username: 'hr',
password: 'hr_schema_password',
schema: 'HR',
synchronize: false,
logging: true,
extra: {
connectString: 'mydbmachine.example.com:1721/orclpdb1'
},
entities: [
Department, Employee
]
});
try {
let items = await getRepository(Department).find({
where: {
DEPARTMENT_ID: LessThan(100)
},
relations: [ 'MANAGER' ],
take: 2
});
console.log(items);
const qb = getRepository(Department).createQueryBuilder('d');
qb.innerJoinAndMapOne(`${qb.alias}.MANAGER`, Employee, 'e', 'd.MANAGER_ID = e.EMPLOYEE_ID')
.limit(2);
items = await qb.getMany();
console.log(items);
} catch (err) {
console.error(err);
}
await connection.close();
})();
[
Department {
DEPARTMENT_ID: 10,
DEPARTMENT_NAME: 'Administration',
MANAGER_ID: 200,
LOCATION_ID: 1700,
MANAGER: Employee {
EMPLOYEE_ID: 200,
FIRST_NAME: 'Jennifer',
LAST_NAME: 'Whalen'
}
},
Department {
DEPARTMENT_ID: 20,
DEPARTMENT_NAME: 'Marketing',
MANAGER_ID: 201,
LOCATION_ID: 1800,
MANAGER: Employee {
EMPLOYEE_ID: 201,
FIRST_NAME: 'Michael',
LAST_NAME: 'Hartstein'
}
}
]
[
Department {
DEPARTMENT_ID: 10,
DEPARTMENT_NAME: 'Administration',
MANAGER_ID: 200,
LOCATION_ID: 1700,
MANAGER: Employee {
EMPLOYEE_ID: 200,
FIRST_NAME: 'Jennifer',
LAST_NAME: 'Whalen'
}
},
Department {
DEPARTMENT_ID: 20,
DEPARTMENT_NAME: 'Marketing',
MANAGER_ID: 201,
LOCATION_ID: 1800,
MANAGER: Employee {
EMPLOYEE_ID: 201,
FIRST_NAME: 'Michael',
LAST_NAME: 'Hartstein'
}
}
]