Компоненты DOCI для прямого доступа к Oracle

Version 1.15

Copyright © 1998-2001 by Andrey Romanchenko
All rights reserved.

e-mail:   lasersquad@tut.by
web site:   http://doci.narod.ru/



Компоненты DOCI протестированы и нормально работают под Delphi 4, 5, 6. Вполне вероятно что без каких-нибудь переделок компоненты будут работать и под Delphi 3 (если это кому то актуально). Когда то они работали и под Delphi 3, но с тех пор внесено много изменений которые на Delphi 3 не тестировались.
Если работаете с Delphi 6 то стоит почитать решение проблемы отсуствия файла Proxies.dcu при компиляции приложения использующего Property Editors (Component Editors).



СОДЕРЖАНИЕ


ВВЕДЕНИЕ

Компоненты предназначены для доступа к серверам Oracle 8 из Delphi 4, 5, 6.
Они используют стандартную библиотеку OCI (Oracle Call Interface), которая устанавливается при установе Oracle Client for Windows 9x/NT/2000. Поэтому перед началом работы необходимо установить Oracle Client, ну конечно иметь где нибудь работающий Oracle Server любой Еdition.

Работают только с клиентом Oracle8 и выше (8i), но можно ходить и к Oracle 7, используя клиентов восьмых.
Что касается Delphi 4, 5, 6 - почти ничего специфического нет, кроме того, что используется стандартный редактор TParam, который ранее надо было писать самому. Кто хочет - может заточить под Delphi3 - скажу большое спасибо и различия включу в свой исходник. Так же очень приветствуются любые рекомендации как заточить их под Kylix. Так же если кому надо - портируйте под Oracle7 или Oracle 9 - там ничего сложного нет, но мне пока не на чем отлаживать. Если будете вносить изменения в исходный код то не забывайте присылать их мне.

Поддерживаются оракловские типы BLOB и CLOB.
С версии 1.0 BLOBы работают нормально и у компонент наследников TDataSet. (у наследников TDataSet пока только на чтение)

Кто интересуется изменениями смотрите ChangeLog.

Я постараюсь преложить все усилия по отлову багов, но большую роль играют ваши отзывы и описание замеченных недостатков - не все я могу самостоятельно отловить.

Мой e-mail - lasersquard@yahoo.com, или lasersquad@tut.by.

Кто хочет получать свежие версии и патчи - не стесняйтесь, пишите мне письмо.

Пока нету сached updates и полей Int64.
Если срочно нужно cached updates или Int64 то пишите мне и они быстрее будут готовы.


РАСПРОСТРАНЕНИЕ

Принцип распространения - Freeware с исходниками.
Вы можете использовать их в каких угодно проектах (в том числе и коммерческих).
Вы так же можете делать любые изменения в исходных кодах, но об всяческих изменениях желательно оповещать автора (то есть меня). Я внесу Ваши изменения в код и выложу обновленные версии на общее обозрение.


ОБЩЕЕ ОПИСАНИЕ

В этом разделе вы найдете общее описание возможностей компонентов.

В настоящее время поддерживаются данные следующих типов (в скобках указан соответствующий тип Oracle):
  • String (CHAR, NCHAR, VARCHAR2, NVARCHAR2, ROWID(пока не поддерживается)) - в памяти как строка символов фиксированого размера как поле
  • Boolean - как NUMBER(1) - 1 байт. Нулевые значения - False, не нулевые - True
  • Double (NUMBER(n,m))
  • Currency
  • Date (DATE) - хранится как количество (integer) дней с 1.01.0001
  • Time (DATE) - хранится как количество (integer) миллисекунд с полуночи
  • DateTime (DATE) - хранится как число int64 которое вычисляется как Date*MSecsPerDay+Time
  • Integer (NUMBER(n) при n меньше 10 если не изменено с помощью TOraDB.Preferences.IntegerPrecision)
  • SmallInt(NUMBER(n) при n меньше 5 если не изменено с помощью TOraDB.Preferences.SmallIntPrecision)
  • Word
  • BLOB (BLOB,BFILE)
  • CLOB (CLOB)
Все вышеуказанные типы поддерживаются в полях.
В параметрах поддерживаются все кроме BLOB и CLOB. NUMBER(n,m) в зависимоcти от значения TOraDB.Preferences.FloatPrecision может быть распознан как String. Это может быть полезно когда в базе хранятся числа с точностью превышающей точность типа Double в Delphi. В этом случае что бы не потерять точность такие числа преобразовываются в String. Для более подробной информации см. описание свойства TOraDB.Preferences.FloatPrecision.


Описание классов:

TOraDB - коннект к базе и управление транзакциями. Для хождения к базе все компоненты используют этот компонент. Все вызовы OCI сосредоточены именно в этом компоненте.

TAOraSQL - непосредственно выполняет вызовы OCI обращаясь к методам TOraDB (выполнение запросов и кусков PL/SQL кода). Является полнофункциональным компонентом, применяется для случаев когда НЕ нужна совместимость с TDataSet, а именно если нужно выполнить хранимую процедуру или кусок PL/SQL кода или запрос результаты которого не нужно показывать в TDBGridе. Работает быстрее TOraSQL т.к не выполняет лишних действий связаных с совместимостью с TDataSet.
Позволяет обращаться к результатам запроса по номеру строки.
За одно обращение к базе вытягивает столько записей сколько указано в свойстве FetchCount. При работе с большими таблицами рекомендуется увеличивать значение FetchCount. По умолчанию FetchCount=100 что соответствует средним размерам данных. Если сделать ему просто Open то запрос откроется, но никакие данные не вытянутся для этого надо использовать либо ReadAll после Open либо OpenAll вместо Open. В этих случаях на клиента вытянутся все строки запроса. Если все строки не нужны то можно использовать ф-цию ReadRecord(RecordNum), которая будет тянуть по FetchCount записей за раз пока не будет вытянуто больше или столько же строк сколько затребовали.

TOraSQL - wrapper вокруг TAOraSQL для совместимости с TDataSet. Аналог TQuery, TStoredProc. Позволяет задать запрос к базе, поля (програмно и в дизайнере), в общем работа с TOraSQL идет как со стандартными компонентами Delphi для доступа к данным. По умолчанию при открытии запроса вычитывается столько записей сколько надо для показа в гриде. Что бы прочитать больше записей можно использовать методы OpenAll, ReadAll, VGoto.

TAOraUpdateSQL - компонента для подсоединения к TOraSQL и задания запросов на изменение (INSERT, DELETE, UPDATE) данных. Является аналогом TUpdateSQL в Delphi. Запросы на изменения данных можно писать и вручную в свойства DeleteSQL, InsertSQL, ModifySQL.

TMemoryDataSet - таблица в памяти наследница TDataSet. Позволяет хранить в памяти и показывать данные в TDBGride данные любого размера. Не связана ни с какими базами данных.

TAMemoryDataSet - таблица в памяти не совместимая с TDataSet. Применяется когда надо хранить в памяти данные организованные подобно таблице, но не нужно их показывать в TDBGridе. Работает быстрее TMemoryDataSet.


Основные файлы:

DynamicArrays.pas - мои компоненты для работы с динамическими массивами. используются многими другими компонентами. Этот модуль может использоваться отдельно от dOCI компонент т.к. содержит много очень полезных и мощных классов для работы с массивами в памяти.

VirtualDataSet.pas - некоторое усовершенствование TDataSet для удобства. от него наследуются все компоненты требующие совместимости с TDataSet.

DataSetQuery.pas - содержит класс-наследник TVirtualDataSet, который содержит 90% функциональности конечных компонент. Для разработчика компонент класс TDataSetQuery представляет наибольший интерес т.к. с перекрытием нескольких методов из него можно сделать нормальный компонент для доступа к любым данным (например легко сделать MemoryTable). Содержит так же класс TABlobStream, который используется внутри TDataSetQuery для доступа к полям типа BLOB.

OraDB.pas - содержит компонент TOraDB для коннекта к Ораклу, аналог TDatabase в Delphi.

AOraSQL.pas - содержит непосредственно класс TAOraSQL и используемые им же 2 класса TAOraField и TAOraParam для представления полей и параметров запроса.

OraSQL.pas - содержит класс TOraSQL.

OraDefines.pas - содержит константы и определения функций для OCI вызовов.

OraError.pas - содержит классы и функции для работы с исключениями (EOraError, ADatabaseError).

MemoryDataSet.pas - содержит класс TMemoryDataSet наследник TDataSet для хранения таблиц в памяти. Практически то же что и TOraSQL не связан с базами. Может показывать данные в TDBGride.

AMemoryDataSet.pas - содержит класс TAMemoryDataSet для хранения данных в памяти когда не нужна совместимость с TDataSet. Работает быстрее TMemoryDataSet и рекомендуется к использованию когда не нужна совместимость с TDataSet.

AOraUpdateSQL.pas - содержит класс TAOraUpdateSQL для аналог стандартного TUpdateSQL

dOCIMessages_LANGUAGE.lang - ресурсный файл со строками сообщений об ошибках. Таких файлов может быть несколько по одному для каждого языка. Пока есть только два языка - русский и английский (файлы dOCIMessages_Russian.lang и dOCIMessages_English.lang соответственно). Те кому нужны другие языки переводите один из существующих и присылайте его мне я включу его в дистрибутив. Какой ресурсный файл будет использоваться задается в dOCI.inc и dOCIMessages.pas с помощью условной компиляции.

GoodDate.pas - содержит множество полезных функций для работы с датами в различных форматах.

OraUtils.pas - содержит различные полезные функции используемые в компонентах.


ИНСТАЛЯЦИЯ

Откройте package dOCI5.dpk (dOCI6.dpk для Delphi 6). Нажмите кнопки "Compile", а потом "Install" и компоненты установятся. Искать их следует на странице "Data Access" палитры компонентов Delphi.

КАК РАБОТАТЬ С КОМПОНЕНТАМИ

Здесь приводится краткое описание основных свойств и методов компонентов. Полезно для общего знакомства с применением и со структурой компонентов.
TOraDB - для коннекта к Oracle (аналог TDatabase в Delphi)

Свойства :
  • Active - и так ясно
  • DBLogin, DBPassword - имя и пароль в базу
  • DBServer - синоним сервера к которому конектимся (создается с помощью "Oracle Net8 Easy Config" либо ручками прописывается в файле %oraclehome%/net80(network)/admin/tnsnames.ora)
  • OraSessionIsolationLevel - уровень изоляции транзакций для сессии. Все начинающиеся в этой секции транзакции будут иметь этот уровень изоляции (если он не переопределен с помощью OraTransIsolationLevel).
  • OraTransIsolationLevel - уровень изоляции новой транзакции. Если tiDefault то уровень берется из OraSessionIsolationLevel.
Методы:
  • Open, Close - сконектиться/отконектиться
  • StartTransaction, CommitTransaction, RollbackTransaction - управление транзакциями.

TOraSQL - запросы к Oracle (совместима с TDataSet)

Свойства :
  • Database - к какой базе ходить(компонента TOraDB)
  • SQL - текст запроса (как всегда - параметры начинаются с ':')
  • Params - список параметров.
  • FetchCount - для SELECT - сколько записей вытягивать за одно обращение к серверу. Как показывает практика, значение на уровне 1 - это примерно скорость BDE.
    Методы:
  • Open, Close - открыть/закрыть запрос (только для SQL запросов вида SELECT ...)
  • ExecSQL - для выполнения всех других видов запросов кроме SELECT.
  • Prepare - подготовить запрос к выполнению. Вызывать необязательно.
  • UnPrepare - освободить привязку, сделаную Prepare. Вызывать необязательно.

Доступ к данным рекомендуется делать через следующие методы :
  • GetFieldValue - получить значение поля. Намного быстрее FieldByName('').As... но неправильно отдает значения записей находящихся в режиме редактирования.
  • GetFieldHArray - получить указатель на массив значений поля
  • GetFieldNullHArray - получить указатель на массив признаков Null или NOT Null (по последним 2-м методам полезно внимательно просмотреть файл DynamicArrays.pas)
  • ReadAll - прочитать все данные с сервера на локальную машину
  • VGoto - прочитать все записи до указаной, если они еще не прочитаны

TAOraUpdateSQL - запросы изменения данных
DeleteSQL, InsertSQL, ModifySQL - и так понятно для чего предназначены

Работа с BLOB :
При работе с TOraSQL BLOB поля можно читать используя стандартные методы от TDataSet.
Для записи пока надо использовать TAOraSQL. Что бы можно было записывать поля BLOB запрос должен содержать фразу "FOR UPDATE".

TAOraSQL имеет следующие функции для работы с BLOB:
  • GetLobLength - получить размер данных в байтах содержащихся в поле.
  • ReadBlob - читает данные из заданного BLOB поля в буфер.
  • WriteBlob - записывает данные из заданного буфера в BLOB поле.
  • ReadBlobToStream - читает весь BLOB в поток
  • WriteBlobFromStream - перезаписывает BLOB поле из потока
  • WriteBlobParam not implemented
  • ReadBlobParamnot implemented

ПРИМЕРЫ

Получение курсора из запроса: Для этого надо написать запрос, параметром которого является курсор и присвоить этому параметру тип данных ftCursor и тип параметра ptResult. Например, вызов StoredProc, возвращающей курсор :

BEGIN :Result := GetData(12); END;

!!!! В тексте SQL можно писать PL/SQL-блок.

Если запрос достает одну запись: Если надо вытянуть запросом всего несколько чисел (запрос такой что возвращает несколько полей из одной строки таблицы), то лучше использовать для этого параметры, а не поля, например :

BEGIN SELECT Name,Index INTO :Name,:Index FROM Table1 WHERE ...... ; END;

и результат получать через параметры
Name:=OraSQL.ParamByName('Name').AsString; Ind:=OraSQL.ParamByName('Index').AsInteger;
типы параметров Name и Index надо будет задать в дизайнере или в коде программы.


ТЕСТЫ НА ПРОИЗВОДИТЕЛЬНОСТЬ

Приблизительные замеры скорости показали(секунды) :
            BDE        OCI(FetchCount=1)   OCI(FetchCount=1000)
INSERT 24 19
SELECT 27 26 4
Тесты выполнялись :
сервер - oracle 8.0.5(linux) - p-200/64ram
клиент - NT4 - pII-233/64ram
сетка - 10мбит незагруженная
работа шла с небольшой таблицей в 10000 записей