пятница, 24 февраля 2012 г.

Oracle дома. Быстрый старт. Часть 4: из Delphi в Oracle

Этот пост является продолжением серии постов “Oracle дома. Быстрый старт” (часть 1, часть 2, часть 3).

Прежде чем начать что-то делать в Delphi, рассмотрим некоторые инструменты, которые мы могли бы использовать для работы с Oracle. Грубо их можно разделить на две категории:

  1. Встроенные компоненты Delphi.
  2. Сторонние компоненты.

Встроенные компоненты Delphi

Я вкратце напишу только о тех, с которыми мне довелось пользоваться на практике. А это:

BDE – это уже устаревший механизм, с ним конечно связано много воспоминаний (как положительных, так и отрицательных), но его настоятельно не рекомендуется использовать в новых проектах и в Delphi он оставлен лишь для совместимости. К главным его недостаткам можно отнести необходимость “тащить” дистрибутив BDE при распространении своего приложения.

dbGo, ранее называлось ADO – это набор компонентов, которые используют ActiveX технологию ADO. Сам по себе этот инструмент удобный и достаточно универсальный, если предполагается работать с разными СУБД. Более того, библиотеки ADO входят в последние версии Windows и не требуют дополнительной установки. Однако для работы с конкретной СУБД используется дополнительный ODBC-драйвер, который может потребовать дополнительной конфигурации. Да и вообще работа с базой данных тормозиться, тут цепочка вызовов примерно такая: <Ваш код> – <Компоненты dbGo> – <ActiveX ADO (библиотеки COM)> – <OLEDB драйвер / OLEDB + ODBC драйвер (dll)> – <клиентское ПО (oci.dll)> – <СУБД (Oracle)>.

dbExpress – это механизм, который пришёл на смену BDE в Delphi 6. Вот несколько ссылок о причинах его появления и трудностях его использования: Технология dbExpress, Quick Guide: dbExpress, Перенос приложений с BDE на dbExpress. В отличии от ADO, тут цепочка короче: <Ваш код> – <Компоненты dbExpress> – <драйвер dbExpress для работы с конкретной СУБД (dll)> – <oci.dll> – <СУБД>, причём компоненты dbExpress являются простой (не COM) обёрткой над драйвером-библиотекой. Однако и тут цепочка получается длинной, более короткую можно получить только с использованием сторонних компонентов.

 

Сторонние компоненты

Их существует великое множество. Но мы определились, что будем работать с Oracle, а это значительно сужает круг. Скажу сразу, что я пользовался не всеми, но на слуху следующие компоненты:

  • DOA
  • ODAC
  • AnyDAC

Использование сторонних компонентов позволяет сократить цепочку вызовов до такой: <Ваш код> – <Компонент> – <oci.dll> – <Oracle>, что является самым оптимальным.

DOA (Direct Oracle Access) – это набор компонентов, предлагаемых компанией Allround Automations (AA), которая знаменита продуктом PL/SQL Developer. (Кстати сказать, PL/SQL Developer  – это наверное один из лучших продуктов для кодирования и отладки pl/sql кода в Oracle, но он платный.) PL/SQL Developer использует именно DOA. Честно говоря – я не пользовался этими компонентами, но мне довелось однажды писать плагин для PL/SQL Developer – там всё более чем прозрачно и понятно. Немного погуглив, могу голословно заявить следующее: DOA является стабильным и простым для усвоения (даже для новичков) набором компонентов. Однако скорость его развития сильно зависит от нужд PL/SQL Developer’а. Ну т.е. с появлением новых версий Delphi разработчики AA не сильно то и торопятся обновлять свои компоненты. Скорее даже так: частота обновлений DOA зависит от появлений новых версий Oracle. Стоимость DOA колеблется от $129 до $578. Если бы я покупал DOA, то выбрал бы комплектацию за $478.

ODAC (Oracle Data Access Components) – продукт компании Devart – монстра всевозможных решений для разных СУБД, языков программирования и платформ. (Мне однажды потребовалось написать программу (2007 год), которая бы с КПК (Pocket PC) подключалась бы напрямую к БД – у Devart мы нашли необходимые библиотеки и компоненты.) Отличительной особенностью ODAC является возможность подключения к Oracle напрямую, в обход oci.dll (так называемый Direct Mode), т.е. цепочка подключения будет самой короткой: <Ваш код> – <ODAC> – <Oracle>, а значит и самой быстрой. Правда там есть некоторые ограничения и Devart не рекомендует им пользоваться в общем случае, т.е. рекомендует пользоваться режимом с использованием oci.dll. И ещё одно “кстати”: ODAC вроде как уже поддерживает FMX, когда как конкуренты – пока ещё нет. Стоимость ODAC для одного пользователя колеблется от $149.95 до $499.95. Для себя я бы выбрал версию за $449.95.

AnyDAC (Universal Data Access Components) – разработка компании DA-SOFT Technologies. Вообще, ещё до появления AnyDAC, были компоненты NcOCI7, а затем FreeDAC – бесплатные разработки Дмитрия Арефьева, с которыми я в основном и работал. И именно обёртка над oci.dll из состава компонент FreeDAC сейчас используется у нас в компании (а далее у нас используются самописные компоненты, которые по скорости работы с Oracle не уступают другим компонентам). К плюсам этой библиотеки можно отнести отзывчивость и быструю реакцию со стороны службы поддержки. А при желании можно договориться и о скидках :с). Стоимость AnyDAC для одного пользователя составляет $399.

 

Что выбрать?

Если Вы собираетесь писать серьёзный проект, то по-любому лучше выбрать сторонние компоненты. Какой именно компонент выбрать – однозначного ответа Вам никто не даст: каждый будет говорить о “своих” плюсах.  Я же давно собираюсь написать объективное тест-приложение для сравнения этих компонентов между собой, но всё никак не доходят руки это сделать. И в интернете напрямую их особо никто и не сравнивает (по крайней мере исходников тестов я не нашёл).

UPD: ссылка по теме.

А для начала мы выберем dbExpress – родной для Delphi механизм, по которому достаточно примеров можно найти в глобальной сети.

 

Итак

Запускаем Delphi, создаём новое VCL приложение. “Кидаем” на форму компоненты и настраиваем их:

dbExpress \ TSQLConnection –> SQLConnection1

SQLConnection1.Driver = Oracle
SQLConnection1.Driver.Database = //192.168.56.101/orcl
SQLConnection1.Driver.UserName = scott
SQLConnection1.Driver.PassWord = oracle
SQLConnection1.LoginPrompt = False
SQLConnection1.Connected = True – это вызовет попытку подключения к БД, убедитесь, что к ней можно подключиться (запустив, например, SQLTools).

dbExpress \ TSimpleDataSet –> SimpleDataSet1

SimpleDataSet1.Connection = SQLConnection1
SimpleDataSet1.DataSet.CommandText = select * from emp
SimpleDataSet1.Active = True

 

Data Access \ TDataSource –> DataSource1

DataSource1.DataSet = SimpleDataSet1

 

Data Controls \ TDBGrid –> DBGrid1

DBGrid1.Align = alClient
DBGrid1.DataSource = DataSource1

Всё :с) Уже в Design-Time мы увидим результат выборки из таблицы emp. Можно запустить приложение и увидеть это в run-time. Приложение получилось настолько простым, что я не стал делать ни скрин-шотов, ни выкладывать какие-либо исходники. А дальше – добро пожаловать в мир разработки приложений для работы с базами данных :с).

10 коммент.:

Unknown комментирует...

ADO:
[Ваш код] – [Компоненты dbGo] – [ActiveX ADO (библиотеки COM)] – ([OLEDB драйвер] _ИЛИ_ ([Мост OLEDB-ODBC]+[ODBC драйвер (dll)])) – [клиентское ПО (oci.dll)] – [СУБД (Oracle)]

Упустили из значительных:

1) ncOCI8 - предок AnyDAC
http://www.da-soft.com/NCOCI8Home.html

2) Delphi Direct ORACLE Access Components
http://sourceforge.net/projects/delphioci

3) Pascal Data Objects
http://pdo.sourceforge.net

4) $ SQLDirect http://www.sqldirect-soft.com

5) UniDAC от авторов ODAC

6) ZeosDBO
http://sourceforge.net/projects/zeoslib

7) vkNLO Vlad Karpov Native Link to Oracle
http://vlad-karpov.narod.ru/Aticles/Vknlo/VKNLO.htm

Это не считая еще и простых=максимально легких оберток над OCI.

В общем есть из чего выбрать.
У всех есть плюсы-минусы.

Практически все старые компоненты вышли на цикл поддержки(насыщения) - фиксов и добавления поддержки новых сред. То есть стабильны.

Сравнительная таблица технологий доступа к СУБД Oracle из D.TDelphi
http://www.tdelphiblog.com/2009/02/oracle-delphi.html

Николай Зверев комментирует...

Unknown, спасибо. Тем кто выйдет на этот пост поиском, Ваш комментарий может быть полезен.

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

Aleksey Timohin комментирует...

Я для бакалаврской работы писал тестовую программку, которая подключалась к Oracle используя разные либы. Проверял как разные либы работают с разными типами данных Oracle (основной упор был на сложные типа, типа объектных полей и вложенных таблиц). Прока от такого тестирования объектных типов никакого не было. Но это я понял уже при обработке результатов. 90% теста делала программка. Нужные либы подключались/отключались директивами.
В общем, если интересно, могу скинуть её исходники. Если что, пиши в скайп или на мейл. Адреса есть у меня в блоге в на страничке About.

Проверил работу:
1) ADO
2) dbExpress
3) ODAC
4) AnyDac
5) DOA
6) ZeosLib
7) SQLDirect

Николай Зверев комментирует...

Алексей, конечно интересно! Сейчас напишу..

Анонимный комментирует...

а можно dbxdrivers.ini и dbxconnections.ini, для всего выше описанного выложить?

Николай Зверев комментирует...

А я их и не настраивал (даже не знаю, есть ли они у меня после чистой установки Delphi), достаточно настроить компонент TSQLConnection как показано в примере:
.Driver = Oracle - говорит о том, что будем подключаться через oci.dll (для этого надо установить oracle-клиент, см. предыдущую заметку)
.Driver.Database = //192.168.56.101/orcl - это host и sid запущенной СУБД (см. предыдущую заметку)
.Driver.UserName = scott - это логин
.Driver.PassWord = oracle - это пароль
.LoginPrompt = False - не спрашивать пароль при подключении к БД (т.к. он уже указан). Можно оставить True, тогда будет предложен стандартный диалог для ввода логина и пароля.

Николай Зверев комментирует...

Ну да, конечно же они есть. Однако dbxconnections.ini не нужен, т.к. все настройки задаём явно, а dbxdrivers.ini содержит (касательно Oracle) такие строки:
[Installed Drivers]
Oracle=1

[Oracle]
GetDriverFunc=getSQLDriverORACLE
LibraryName=dbexpora.dll
VendorLib=oci.dll
DataBase=Database Name
User_Name=user
Password=password
BlobSize=-1
ErrorResourceFile=
LocaleCode=0000
Oracle TransIsolation=ReadCommited
RowsetSize=20
OS Authentication=False
Multiple Transaction=False
Trim Char=False

Vad комментирует...

Спасибо за статьи, очень помогли.
Однако, не получается пока вывод русских букв из таблиц. Delphi отображает ?????
Сервер ставил сам.
SELECT USERENV ('language') FROM DUAL
-> RUSSIAN_RUSSIA.CL8MSWIN1251
Клиент - как тут описано сделал.
Утилита SQLTools так же выводит ?????, а SQLDeveloper - выводит корректно.
Видел что-то про реестр, актуально это для oci.dll?
Не подскажете, где копать? Спасибо.

Николай Зверев комментирует...

Проблема связана с тем, что SQLTools и некоторые компоненты Delphi работают с oci.dll в обычном, не юникодном режиме. Для того, чтобы кириллица отображалась на клиенте корректно, необходимо подсказать клиенту, в какой кодировке работать. Ну и не забыть выбрать шрифт, поддерживающий киррилицу - Tahoma или Arial, к примеру.

С кодировкой - см. параметр NLS_LANG. Это может быть параметр среды окружения (как его заводить - см. часть 3 серии, где заводится переменная TNS_ADMIN, в своих же Delphi-приложениях я его задаю функцией SetEnvironmentVariable, чтобы пользователю не объяснять, как его заводить в системе). Либо это может быть значением в реестре, но чтобы знать, как это завести, нужно знать, как oci.dll считывает настройки из реестра, а этот алгоритм может меняться от версии к версии.
Впрочем, значение переменной среды окружения имеет приоритет над реестром, поэтому рекомендую с реестром вообще не заморачиваться.

Попробуйте такие значения параметра NLS_LANG:
NLS_LANG=AMERICAN_AMERICA.CL8MSWIN1251
или
NLS_LANG=AMERICAN_AMERICA.UTF8
(В 10й версии oracle-клиента оно работает, а в 11й почему-то мне выдало ошибку - я не стал разбираться, и поэтому и не стал об этом упоминать в заметках. Видимо зря.)

А ещё можно задать параметры:
NLS_NUMERIC_CHARACTERS=.,
NLS_DATE_FORMAT=DD.MM.YYYY HH24:MI:SS

Vad комментирует...

Спасибо, все получилось.
Для SQLPlus батник написал такого содержания:

chcp 1251
set NLS_LANG=AMERICAN_AMERICA.CL8MSWIN1251
sqlplus user_name/user_pass@winm2

+ в консоли шрифт "Lucida"

Отправить комментарий

.

.