Oracle oci что это
OCCI - расшифровывается как Oracle C++ Call Interface и представляет собой специализированное апи для работы с СУБД Oracle используя C++ что в общем то явствует из названия. Для использования необходимо подключить заголовочный файл "occi.h".
Принятые именования объектов Environment* env;
Connection* conn;
Statement* stmt;
ResultSet* rs;
SQLException &sqlExcp;
Давайте рассмотрим пример небольшой тестовой программы использующей интерфейс OCCI:
Сборка программы для Linux, обратите внимание на пути к заголовочным файлам (-I) и библиотекам (-L)
- OCI Shared Library (libociei.so on Solaris and oraociei10.dll on Windows); correct installation of this file determines if you are operating in Instant Client mode
- Client Code Library (libclnstsh.so.10.1 on Solaris and oci.dll on Windows)
- Security Library (libnnz10.so on Solaris and orannzsbb10.dll on Windows)
- OCCI Library (libocci.so.10.1 on Solaris and oraocci10.dll on Windows)
Более подробную информацию можно получить здесь: Instant client.
Рассмотрим базовые объекты используемые программой.
Environment - предназначен для создания среды управления памятью и ресурсами для других объектов OCCI. Объекты создаются в рамках среды, программа может иметь несколько сред, среда может иметь несколько соединений(даже к разным базам) или пулов соединений. Доступные режимы создания
- OBJECT - использование объектных расширений Oracle напрямую в программе на C++. Через специальную утилиту возможно подключение к базе и создание прототипов объектов хранящихся в базе прямо в виде классов C++. Например этот режим необходим для работы объекта Date из состава OCCI.
- SHARED - данные разных запросов(курсоров) используются повторно, т.е. экономится память и время выполнения.
- THREADED_MUTEXED - для использования разными потоками(в многопоточном приложении) без применения синхронизации - она обеспечивается автоматически для Environment, Map, ConnectionPool, Connection.
- THREADED_UNMUTEXED - синхронизацию должно обеспечить приложение.
- execute: Выполнить любой не специфичный запрос
- executeUpdate: Выполнение DML и DDL
- executeQuery: Запрос в базу, предполагает возвращение результата
Позволяет выполнять не только SQL-выражения но и PL/SQL(обрамленный BEGIN/END;)
ResultSet и Connection не рассматриваются, предлагаю обратиться к документации за информацией по этим объектам.
Работа с параметризованными запросами
Обычно запросы содержат переменные в своем составе, например в предложении WHERE. Для эффективной работы с такими запросами используются параметризованные запросы. Конечно, запрос может быть и не параметризованным - собираться программой динамически, а затем подаваться для создания Statement - однако это не самый легкий(применительно к С++) и что самое главное далеко не оптимальный подход.
Если вы разрабатываете приложения под Oracle то скорее всего в курсе некоторых вопросов повышения производительности приложений, одним из которых является применение связываемых переменных. Использование связываемых переменных уменьшает количество жестких разборов sql-выражений, снижает нагрузку на разделяемый пул и в итоге может значительно увеличить скорость работы. Аналогичная ситуация с многократным использованием курсора - уменьшается число мягких разборов и т.д. - речь сейчас не об этом. Должен добавить только что в случае если вы узнали о работе со связываемыми переменными из того, что я написал выше - скорее всего вам следует почитать Т. Кайта "Oracle для профессионалов", главу "Стратегии и средства настройки".
Вернемся к делу - параметризованный запрос это sql-выражение на месте переменных(не обязательно всех) стоят идентификаторы подставляемых значений - ":1", ":var", ":data1". Перед использованием их надо связать с конкретными величинами - это производится вызовом метода stmt->setXXX(setString, setInt, ….) . Для более скоростной обработки можно использовать stmt->setDataBuffer , отличие этого метода от setXXX в том что методы setXXX копируют содержимое источника в выделяемый OCCI буфер что может снизить производительность приложений при больших размерах источника данных. В противоположность setXXX setDataBuffer использует в качестве источника непосредственно переданный параметр, без выделения памяти и копирования. Если вы используете setXXX - сразу после вызова метода можно менять источник, что недопустимо при использовании setDataBuffer
Вот участок кода иллюстрирующий вышесказанное:
- stmt->setAutoCommit(false); - для информации, чтобы не было автоматических фиксаций транзакций при каждом выполнении, по умолчанию стоит false.
- Переменные в Statement* присваиваются по порядку следования в выражении. В случае если вы напишите, к примеру
"Insert into test(field_1,field_2) values(:2,:1)" и прикрепите переменные используя
setInt(1,10);
setInt(2,20);
переменная с именем :2 получит значение 10, c именем :1 - соответственно 20 - Особое внимание следует уделить методу fromText - он очень полезен если в базу нужно ввести число, например типа unsigned long long - прямое присваивание в этом случае не возможно, удобно использовать метод fromText. Нужно помнить что он не срабатывает после того как к объекту применялся метод setNull() - сначала нужно инициализировать объект просто присвоив ему начальное значение. С типом Date аналогичная ситуация, кроме того env должен быть создан с параметром OBJECT. Также для работы метода требуется явное указание параметров nlsParam.
- При присоединении данных переменной длины к повторно используемому курсору(например строк) выделяйте изначально достаточно места в буфере вызывая setString c параметром максимальной длины. Например:
Работа с переменными IN/OUT, OUT
Мы рассмотрели только переменные передаваемые в режиме IN, но OCCI позволяет работать с OUT & IN/OUT. Такие переменные актуальны в случае использования так называемых callable statemens - имеется виду вызов процедур и функций на PL/SQL.
Рассмотрим работу с такими запросами. Предположим, в базе имеется функция на PL/SQL, вот ее прототип:
Пример работы с ней:
- Регистрировать параметры нужно указывая их максимальную длину
- Устанавливать значения параметров IN/OUT после регистрации, иначе значение будет потеряно
Повышение производительности
Как упоминалось ранее для приложений, в которых скорость выполнения запросов является критичной можно использовать функцию setDataBuffer.
paramIndex Номер параметра buffer указатель на буфер с данными type Тип данных в буфере size Размер элемента в буфере length Текущая длина данных в текущей ячейке буфера ind Индикатор. Указывает когда данные пустые, в случае если -1 было вставлено NULL - значение, в случае вызова подпрограммы в запросе -1 указывает что возвращено NULL. rc Код возврата. Этот параметр неприменим к данным передаваемым методами Statement-a, но для данных возвращаемых из вызовов процедур возвращает параметро-зависимый код ошибки.
При инициализации данных используя setDataBuffer данные считываются последовательно из памяти, т.е. после каждой итерации(количество заранее указывается) происходит смещение указателя на адрес следующего элемента. Метод setDataBuffer можно использовать совместно с Statement* stmt->setXXX или без него. Рассмотрим оба варианта использования этого метода
Допустим, в базе создана таблица следующей вида:
Код выполняющий вставку в таблицу:
Важно понимать, что в данном случае объявление char vals[4][10] = ; нельзя заменить на char* vals[4] - и заполнить адреса произвольно, данные должны идти последовательно. Теперь рассмотрим тот же вариант, но когда все данные содержатся в массивах:
В использовании stmt->setMaxIterations(4); нет необходимости Подобным образом можно не только вставлять данные, но и извлекать их. Код из документации по OCCI иллюстрирующий это:
Заключение
В общем, это все что я хотел написать - надеюсь приведенные здесь примеры помогут вам быстро начать использование Oracle в ваших проектах на C++. OCCI очень простой и мощный интерфейс работы с Oracle. Здесь не затронуты вопросы использования BLOB, использование потоков Stream, объектное программирование и Object Type Translator (OTT), получение метаданных, разработка многопоточных приложений например используя ConnectionPool и т.д. По всем этим вопросам стоит обратиться к документации по Oracle - Oracle C++ Call Interface Programmer’s Guide ссылку на которую я приводил в начале статьи.
Oracle Database supports C and C++ programmers with a choice of high performance APIs, including standards-compliant, open-source and proprietary interfaces.
Object Cache
To support high-performance navigational access of objects, OCI runtime provides an object cache for caching objects in memory.
The object cache supports references ( REF s) to database objects in the object cache, the database objects can be identified (that is, pinned) through their references. Applications do not need to allocate or free memory when database objects are loaded into the cache, because the object cache provides transparent and efficient memory management for database objects.
Also, when database objects are loaded into the cache, they are transparently mapped into the host language representation. For example, in the C programming language, the database object is mapped to its corresponding C structure. The object cache maintains the association between the object copy in the cache and the corresponding database object. Upon transaction commit, changes made to the object copy in the cache are propagated automatically to the database.
The object cache maintains a fast look-up table for mapping REF s to objects. When an application dereferences a REF and the corresponding object is not yet cached in the object cache, the object cache automatically sends a request to the server to fetch the object from the database and load it into the object cache. Subsequent dereferences of the same REF are faster because they become local cache access and do not incur network round-trips.
To notify the object cache that an application is accessing an object in the cache, the application pins the object; when it is finished with the object, it unpins it. The object cache maintains a pin count for each object in the cache. The count is incremented upon a pin call and decremented upon an unpin call. When the pin count goes to zero, it means the object is no longer needed by the application.
The object cache uses a least-recently used (LRU) algorithm to manage the size of the cache. When the cache reaches the maximum size, the LRU algorithm frees candidate objects with a pin count of zero.
Defining User-Defined Constructors in C
When defining a user-defined constructor in C, you must specify SELF (and you may optionally specify SELF TDO ) in the PARAMETERS clause.
On entering the C function, the attributes of the C structure that the object maps to are all initialized to NULL . The value returned by the function is mapped to an instance of the user-defined type.
Example 4-1 shows how to define a user-defined constructor in C.
Example 4-1 Defining a User-Defined Constructor in C
The SELF parameter is mapped like an IN parameter, so in the case of a NOT FINAL type, it is mapped to (dvoid *) , not (dvoid **) . The return value's TDO must match the TDO of SELF and is therefore implicit. The return value can never be null, so the return indicator is implicit as well.
Итоги работы
Вот ссылки на проекты на гитхабе для Windows(Visual Studio) и Linux(NetBeans)
О файлах в проекте
Заголовочные файлы oci.h, ocidem.h, ocidfn.h, ocikpr.h, oratypes.h, orl.h взяты из каталога %ORACLE_HOME%\OCI\include (Может, я их немного модифицировал, чтобы не было неразрешенных зависимостей, но этого я уже точно не помню)
ocipfndfn.h - этот файл с определениями типов указателей на функции составлен мной, тут те OCI функции, которые я использовал в своих проектах.
OraFunction.c - Основной файл проекта, тут определения функций для работы с БД.
OraFunction.h - заголовочный файл с объявлениями функции.
ParseCmdLine.c - функция для парсинга командной строки, для получения логина, пароля и строки подключения к базе. Параметры передаются в утилиту стандартным для Оракловых утилит форматом login/pass@dbconnect.
main.c - функция main.
Что утилита делает
Утилита подключается к базе данных, создает таблицу simple_table, заполняет ее данными, получает из нее данные и удаляет таблицу.
Как скомпилировать
Как и было запланировано с самого начала, для компиляции утилиты не требуется никаких дополнительных файлов и библиотек. Для работы, само собой, требуется установленный Oracle Client либо Instant Oracle Cllient, главное, чтобы была доступна OCI-библиотека.
В настоящее время я работаю в компании, которая очень любит использовать в проектах на PHP СУБД Oracle, причем иногда версии 11g.
Большая часть разработчиков этой компании работает под ОС Windows. За последний месяц несколько из них решили приобщиться к Linux и поставили себе Ubuntu. По прошествии нескольких дней после установки самой ОС, ребята столкнулись с задачей установки драйверов PHP для работы с СУБД Oracle — OCI8 и PDO_OCI на базе Oracle instant client 11.2, которую не смогли решить самостоятельно.
Я не нашел подробного, полностью рабочего мануала на русском, по которому новичок в Linux смог бы выполнить все манипуляции сам. В результате мне пришлось несколько раз проделать серию одних и тех же действий на их машинах и написать мануал, который я вам и представляю.
Мануал написан для пользователей Ubuntu Linux, но с некоторыми изменениями подойдет для пользователей большинства Linux'ов.
Подготовка к установке
- У вас должна быть возможность выполнять команды под администратором;
- У вас должен быть установлен php5 со следующими пакетами (команда установки со списком):
sudo apt-get install php5 php5-dev php-pear php5-cli
sudo pecl install pdo - У вас должна быть установлена библиотека libaio1:
sudo apt-get install libaio1
Установка Oracle instant client
- RPM пакет — Linux, CentOS, Fedora, Red Hat Enterprise Linux, Mandriva Linux, SUSE Linux и д.р. у кого есть поддержка RPM;
- ZIP архив — всем остальным.
- instantclient-basic — сам Oracle instant client
- instantclient-sdk — набор библиотек для разработки приложений под Oracle instant client
- instantclient-sqlplus — SQL*Plus
Перемещаем скачанные файлы в /opt/oracle и переходим в папку назначения (допустим что вы скачали «zip архивы» в папку «downloads» Вашего пользователя):
sudo mv ~/downloads/instantclient-*.zip /opt/oracle/
cd /opt/oracle/
Разархивируем все скачанные архивы:
sudo unzip instantclient-basic-*-*.zip
sudo unzip instantclient-sdk-*-*.zip
Если вы скачивали SQL*Plus:
sudo unzip instantclient-sqlplus-*-*.zip
В итоге в каталоге /opt/oracle был создан, для Oracle instant client 11.2.0.2.0, каталог instantclient_11_2. Переименуем этот каталог в instantclient (если у вас другая версия/каталог измените команду) и перейдем в него:
sudo mv instantclient_11_2 instantclient
cd instantclient
Далее необходимо создать несколько дополнительных каталогов и символьных ссылок для нормальной работы клиента (обратите внимание на версию и если она у вас другая измените команды):
sudo ln -s /opt/oracle/instantclient/libclntsh.so.* /opt/oracle/instantclient/libclntsh.so
sudo ln -s /opt/oracle/instantclient/libocci.so.* /opt/oracle/instantclient/libocci.so
sudo ln -s /opt/oracle/instantclient/ /opt/oracle/instantclient/lib
sudo mkdir -p include/oracle/11.2/
cd include/oracle/11.2/
sudo ln -s ../../../sdk/include client
cd -
sudo mkdir -p lib/oracle/11.2/client
cd lib/oracle/11.2/client
sudo ln -s ../../../ lib
cd -
Создаем конфигурационный файл, в котором будет указан каталог для поиска библиотек Oracle instant client, и подключаем его:
echo /opt/oracle/instantclient/ | sudo tee -a /etc/ld.so.conf.d/oracle.conf
sudo ldconfig
Так как в Ubuntu нет каталога /usr/include/php, а клиент его все равно ищет создадим символьную ссылку на его эквивалент php5:
sudo ln -s /usr/include/php5 /usr/include/php
Устанавливаем OCI8
После всех наших манипуляций расширение oci8 замечательно устанавливается с помощью команды pecl:
sudo pecl install oci8
нас просят ввести путь к Oracle instant client, на что необходимо ответить:
instantclient,/opt/oracle/instantclient
Создаём файл подключения расширения:
echo "; configuration for php oci8 module" | sudo tee /etc/php5/conf.d/oci8.ini
echo extension=oci8.so | sudo tee -a /etc/php5/conf.d/oci8.ini
Устанавливаем PDO_OCI
Скачаем и поместим архив во временную директорию:
sudo mkdir -p /tmp/pear/download/
cd /tmp/pear/download/
sudo pecl download pdo_oci
Извлечем содержимое архива и перейдем к нему:
sudo tar xvf PDO_OCI*.tgz
cd PDO_OCI*
Здесь нам необходимо скорректировать файл config.m4, так как в нем нет данных о нашей версии Oracle instant client, последние изменения датируются 2005 годом. Запускаем любимый редактор и вносим изменения отмеченные "+" (обратите внимание на версию и если она у вас другая измените строчки):
sudo vim config.m4
Далее приведен diff двух файлов:
***************
*** 7,12 ****
--- 7,14 ----
if test -s "$PDO_OCI_DIR/orainst/unix.rgs"; then
PDO_OCI_VERSION=`grep '"ocommon"' $PDO_OCI_DIR/orainst/unix.rgs | sed 's/[ ][ ]*/:/g' | cut -d: -f 6 | cut -c 2-4`
test -z "$PDO_OCI_VERSION" && PDO_OCI_VERSION=7.3
+ elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.11.2; then
+ PDO_OCI_VERSION=11.2
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then
PDO_OCI_VERSION=10.1
elif test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.9.0; then
***************
*** 119,124 ****
--- 121,129 ----
10.2)
PHP_ADD_LIBRARY(clntsh, 1, PDO_OCI_SHARED_LIBADD)
;;
+ 11.2)
+ PHP_ADD_LIBRARY(clntsh, 1, PDO_OCI_SHARED_LIBADD)
+ ;;
*)
AC_MSG_ERROR(Unsupported Oracle version! $PDO_OCI_VERSION)
;;
***************
Подготавливаем окружение для расширения php c помощью команды phpize (обратите внимание на версию, если она у вас другая измените):
sudo phpize
Конфигурируем установщик пакета и устанавливаем пакет (обратите внимание на версию, если она у вас другая измените):
sudo ./configure --with-pdo-oci=instantclient,/opt/oracle/instantclient/,11.2
sudo make
sudo make install
Создаём для него файл подключения:
echo "; configuration for php PDO_OCI module" | sudo tee /etc/php5/conf.d/pdo_oci.ini
echo extension=pdo_oci.so | sudo tee -a /etc/php5/conf.d/pdo_oci.ini
Подводим итоги
Перезапускаем apache и проверяем наличие установленных расширений:
sudo /etc/init.d/apache2 restart
php -m
Заключение
Мануал основан на вот этом посте, который был несколько переработан — исправлены ошибки и внесены дополнения.
OCI is a set of C library functions that applications can use to manipulate data and schemas in an Oracle database.
About Oracle Call Interface (OCI)
OCI supports both traditional 3GL and object-oriented techniques for database access, as explained in the following sections.
An important component of OCI is a set of calls to manage a workspace called the object cache. The object cache is a memory block on the client side that allows programs to store entire objects and to navigate among them without additional round trips to the server.
The object cache is completely under the control and management of the application programs using it. The Oracle server has no access to it. The application programs using it must maintain data coherency with the server and protect the workspace against simultaneous conflicting access.
OCI provides functions to
Access objects on the server using SQL.
Access, manipulate and manage objects in the object cache by traversing pointers or REF s.
Convert Oracle dates, strings and numbers to C data types.
Manage the size of the object cache's memory.
OCI improves concurrency by allowing individual objects to be locked. It improves performance by supporting complex object retrieval.
OCI developers can use the object type translator to generate the C data types corresponding to a Oracle object types.
Oracle Call Interface Programmer's Guide for more information about using objects with OCI
Navigational Access in OCI Programs
OCI programs provide navigational access by means of an API.
In the object-oriented programming paradigm, applications model their real-world entities as a set of inter-related objects that form graphs of objects. The relationships between objects are implemented as references. An application processes objects by starting at some initial set of objects, using the references in these initial objects to traverse the remaining objects, and performing computations on each object. OCI provides an API for this style of access to objects, known as navigational access. Specifically, OCI enables you to:
Cache objects in memory on the client machine
Dereference an object reference and pin the corresponding object in the object cache. The pinned object is transparently mapped in the host language representation.
Notify the cache when the pinned object is no longer needed
Fetch a graph of related objects from the database into the client cache in one call
Create, update, and delete objects in the cache
Flush changes made to objects in the client cache to the database
Закрываем сессию
После нужных операции нужно закрыть сессию:
Закрываем окружение
После того, как взаимодействие с базой больше не нужно, закрываем окружение:
Oracle Call Interface
Oracle Call Interface is the comprehensive, high performance, native C language interface to Oracle Database for custom or packaged applications.
A broad range of customers including Fortune 500 customers and ISVs develop high performance applications directly in Oracle Call Interface.
Oracle Call Interface libraries are included by default in Oracle Database 18c. Oracle Call Interface is also in the lightweight Oracle Instant Client, allowing ISVs and customers to quickly install and deploy Oracle Call Interface applications and tools. See the Oracle Instant Client page for more information.
Oracle C++ Call Interface (OCCI)
Based on the Standard C++ and object-oriented paradigm, OCCI is designed for improved productivity and quality in developing Oracle Database applications.
OCCI is being successfully used for client-server, middle-tier, and complex object modeling applications.
OCCI is the natural interface for accessing Oracle object-relational features like object types, inheritance, relationships and collections. Objects are represented as C++ class instances in OCCI leading to seamless integration between the application and database. The navigational access method with the client object cache provides complete database transparency.
The Oracle ODBC driver for Oracle Database enables ODBC applications to connect to Oracle Database. In addition to standard ODBC functions, users can leverage Oracle specific features for high performance data access.
The Oracle ODBC driver is an ODBC 3.52 compliant driver and is available as an easy to install Oracle Instant Client package.
Хабр, привет! Вообще-то я не настоящий сварщик программист, я системный администратор и администратор БД. Поэтому, когда несколько лет назад передо мной встала задача написать небольшое клиентское приложение для автоматизации рутинных процедур, я потратил немало времени, чтобы разобраться в этом вопросе. Если вдруг у вас примерно такая же ситуация, надеюсь, эта статья сэкономит ваше время и силы.
Подключение библиотеки
Для того, чтобы использовать OCI функции в своей программе, нужно подключить библиотеку и получить адреса функций:
Подключение библиотеки и получений адресов функций
Таком образом нужно получить адреса всех функций, которые мы будем использовать в нашей программе.
Associative Access in OCI Programs
OCI programs support associative access to objects with an API that can manipulate object data.
Traditionally, 3GL programs manipulate data stored in a relational database by executing SQL statements and PL/SQL procedures. Data is usually manipulated on the server without incurring the cost of transporting the data to the client(s). OCI supports this associative access to objects by providing an API for executing SQL statements that manipulate object data. Specifically, OCI enables you to:
Execute SQL statements that manipulate object data and object type schema information
Pass object instances, object references ( REF s), and collections as input variables in SQL statements
Return object instances, REF s, and collections as output of SQL statement fetches
Describe the properties of SQL statements that return object instances, REF s, and collections
Describe and execute PL/SQL procedures or functions with object parameters or results
Synchronize object and relational functionality through enhanced commit and rollback functions
Какую технологию использовать?
Oracle предлагает следующие варианты:
Pro*C/C++ - Предкомпилятор Oracle. Инструмент программирования, который позволяет встраивать операторы SQL в хост-программу высокого уровня. Предварительный компилятор принимает основную программу в качестве входных данных, преобразует встроенные инструкции SQL в стандартные вызовы библиотеки Oracle во время выполнения и создает исходную программу, которую вы можете скомпилировать, связать и выполнить. Разобраться с этим у меня не получилось, поэтому ничего к этому описанию я добавить не могу
C++ Call Interface (OCCI) - API, который предоставляет приложениям C++ доступ к данным в базе данных Oracle. OCCI позволяет программистам на C++ использовать весь спектр операций с базами данных Oracle, включая обработку инструкций SQL и манипулирование объектами. Так как я С++ в реальных проектах не использовал, этот вариант мне явно не подходил
Oracle Call Interface (OCI) - API, который позволяет создавать приложения, использующие вызовы функций для доступа к базе данных Oracle и управления всеми этапами выполнения инструкций SQL. OCI поддерживает типы данных, соглашения о вызовах, синтаксис и семантику C и C++. Он предоставляет библиотеку стандартных функций доступа к базе данных и поиска в виде библиотеки динамической среды выполнения (библиотеки OCI), которая может быть связана в приложении во время выполнения. Также в описании указано, что все оракловые утилиты (типа sqlplus, exp, imp и прочие) написаны именно с использованием OCI. Что же еще нужно?
Oracle Database Programming Interface for C (ODPI-C) - это C-библиотека с открытым исходным кодом, которая упрощает использование общих функций интерфейса вызовов Oracle (OCI) для драйверов баз данных Oracle и пользовательских приложений. DPIC находится поверх OCI и требует клиентских библиотек Oracle. Проект лежит на Гитхабе. Про этот вариант я прочитал только когда писал эту статью. Но, посмотрев примеры программ, я нисколько не пожалел, что выбрал OCI. Может, это вопрос привычки и опыта, но простой эта библиотека мне не показалась.
Building an OCI Program That Manipulates Objects
You can build an OCI program to manipulate objects by representing types in the C host language format.
When you build an OCI program that manipulates objects, you must complete the following general steps
- Define the object types that correspond to the application objects.
- Execute the SQL DDL statements to populate the database with the necessary object types.
- Represent the object types in the host language format.
For example, to manipulate instances of the object types in a C program, you must represent these types in the C host language format. You can do this by representing the object types as C structs. You can use a tool provided by Oracle called the Object Type Translator (OTT) to generate the C mapping of the object types. The OTT puts the equivalent C structs in header (*.h) files. You include these *.h files in the *.c files containing the C functions that implement the application.
Oracle Call Interface Programmer's Guide for tips and techniques for using OCI program effectively with objects
Создание сессии
Для каждой сессии нам нужно инициализировать хендл OCISvcCtx, именно он используется для выполнения sql-выражений. Я, руководствуясь демонстрационными примерами от Oracle, создавал сессии так:
Уже в процессе написания статьи, я увидел, что для этих же целей можно использовать функцию OCILogon2. Судя по всему, это намного проще и удобнее. А главное, нужно меньше писать кода. Но мы уже оставим все, как есть.
Что нужно?
Определившись с требованиями получаем следующее.
Желательно для бинарника:
Небольшой размер исполняемого файла.
Корректная обработка случаев, когда OCI-библиотека недоступна
Необходимо для бинарника:
Работать утилита должна на любом компьютере с ОС Windows выше Windows 7 или Windows Server 2008 без установки каких-либо фреймворков и Runtime Environment. Должен быть установлен только какой-то из продуктов Oracle, включающий OCI-библиотеку.
Очень желательно для исходников:
Чтобы готовый проект можно было без проблем скомпилировать на другом компьютере без установки каких-либо библиотек. Так как у нас есть похожий legacy проект, которую лет 20 назад писал давно ушедший сотрудник. Его рабочую станцию мы храним в виде образа ВМ, так как подготовить окружение на новой рабочей станции - задача крайне нетривиальная.
Oracle Call Interface
Oracle Call Interface is the comprehensive, high performance, native C language interface to Oracle Database for custom or packaged applications.
A broad range of customers including Fortune 500 customers and ISVs develop high performance applications directly in Oracle Call Interface.
Oracle Call Interface libraries are included by default in Oracle Database 18c. Oracle Call Interface is also in the lightweight Oracle Instant Client, allowing ISVs and customers to quickly install and deploy Oracle Call Interface applications and tools. See the Oracle Instant Client page for more information.
Oracle Database Programming Interface for C (ODPI-C)
Oracle Database Programming Interface for C (ODPI-C) is a new open source library of C code that simplifies the use of common Oracle Call Interface features for Oracle Database drivers and user applications.
ODPI-C is a thin layer on top of Oracle Call Interface and requires Oracle client libraries.
ODPI-C's goal is to expose common Oracle Call Interface functionality in a readily consumable way to the C or C++ developer. Oracle Call Interface's API is extremely flexible and is highly efficient, giving very fine-grained control to the developer for a wide range of use cases. ODPI-C is also flexible but is aimed primarily at language driver creators. These creators are programming within the confines of a scripting language's type system and semantics. The languages often expose simplified data access to users through cross-platform, 'common-denominator' APIs. Therefore ODPI-C provides easy to use functionality for common data access, while still providing the power of Oracle Database.
Of course ODPI-C isn't just restricted to drivers. ODPI-C is licensed under the Apache 2.0 and/or the Oracle UPL licenses, so the code can be reused in your own projects.
Инициализация окружения
Далее нам нужно инициализировать структуры OCIEnv (хендл окружения) и OCIError (хендл для обработки ошибок).
Пишем простое приложение
Вставляем данные
Пример функции для загрузки данных в базу:
В целях увеличения быстродействия и экономии ресурсов базы в случае множественных инсертов нужно вначале подготовить выражение с заполнителями типа :id и :string, связать их с соответствующими переменными, и затем изменять значение переменных и выполнять выражение.
Получаем данные
Код для получения данных из базы:
При получении данных поступаем аналогично, привязываем переменные с запрошенными полями в селекте, выполняем выражение и затем в цикле одну за другой получаем строки
Читайте также: