Програмування від Випуск 10

Доброго часу доби, шановні передплатники!

Сьогодні буде продовжено розповідь про компонент TOraQuery.

Минулого випуску ми навчилися виконувати будь-які запити. У більшості випадків потрібно буде вибирати інформацію, яка відповідає будь-яким умовам. Наприклад, можна вибрати лише людей, прізвище яких починається на А:select fam, name, otch, birthday from clientphis where fam like 'А*'Якщо потрібно знайти людей з прізвищем, що починається на Г, то можна звичайно написати такий запитselect fam, name, otch, birthday from clientphis where fam like 'Г*'Як напевно помітили, у нас вийшло два однакових запити, які відрізняються лише умовою відбору записів. Адже таких умов у процесі роботи програми може генеруватися кілька сотень і для Оракла це будутьунікальнізапити, що негативно позначиться на продуктивності та масштабованості всієї системи.

У цій ситуації на допомогу надходять параметричні запити. Вище зазначені запити можна перетворити на параметричний так:select fam, name, otch, birthday from clientphis where fam like :famЗверніть увагу на вираз ":fam" - ця конструкція визначає параметр з іменем fam. Ім'я параметру можна давати будь-яке, а не тільки ім'я поля, але в певних ситуаціях діють деякі правила завдання імен параметрів. До розгляду цих правил ми повернемось у майбутньому.

Перед виконанням такого запиту необхідно обов'язково встановити значення параметрів. Для цього можна використовувати або колекцію Params, яка містить список усіх параметрів запиту (нумерація починається з 0) або метод ParamByName, який працює із зазначеним на ім'я параметром.

Модифікуємо останній наш приклад так, щоб вибирати людей із прізвищем, що починаєтьсяна введені нами символи. 1. Змінимо запит у OraQuery1 наselect fam, name, otch, birthday з clientphis where upper(fam) як upper(:fam)2. Перепишемо обробник OnClick кнопки: Як бачите, немає нічого складного. Зручність параметрів особливо проявляється тоді, коли потрібно працювати з датами, тому що при цьому не потрібно наводити дату до формату, який приймає сервер.

Якщо Ви дочитали до цих рядків, то напевно подумали, що параметри можна використовувати не тільки для визначення значень виразів, але і для визначення полів і таблиць, наприклад, було б непогано виконати такий запит:select * from : table- для вибірки даних з будь-якої таблиці абоselect * from table order by :ordfield- для завдання сортування за будь-яким полем.

На жаль, безпосередньо такі запити жоден сервер не може виконати і відразу видаватиме помилку. Можна звичайно динамічно формувати запит, але ODAC має більш гарне рішення, а самемакроси. Використовувати макроси так само легко, як і параметри. Для завдання макросу використовується символ & (а не :) і для роботи з макросами є метод MacroByName/Macros (порівняйте з ParamByName/Params).

Розглянемо роботу з макросами на конкретному прикладі: Тепер у рядку редагування можна вказати ім'я поля, яким буде йти сортування.

Також макроси можна використовуватиме динамічного завдання умов тощо. без безпосереднього формування потрібного sql-коду, наприклад: MyQuery.SQL.Text := 'SELECT * FROM Dept WHERE DeptNo > 20 &Cond1'; MyQuery.Macros[0].Value := 'and DName is NULL'; MyQuery.Execute; у разі на сервер піде наступний запит: SELECT * FROM Dept WHERE DeptNo > 20 and DName is NULL

Як могли помітити, за допомогоюпараметрів такий запит не можна сформулювати. Але що робити, якщо необхідно періодично відключати умову 'and DName is NULL'? Можна звичайно макросу привласнити порожній рядок, але ODAC містить більш красиве і елегантне рішення - достатньо макросу скинути властивість Active (за умовчанням воно встановлено): MyQuery.Macros [0]. Active: = False; в цьому випадку на сервер піде запитSELECT * FROM Dept WHERE DeptNo > 20

У використанні макросів і параметрів немає нічого хитромудрого, так що сміливо беріть ці можливості на озброєння. І не забувайте, що Оракл дуже любить параметричні запити.

Настав час для зв'язку master/detail. Що це за зв'язок я розповідати не буду, тому що це виходить за рамки статті. Просто розповім, якими способами в ODAC'і її можна організувати.

Якщо звернули увагу на словосполученняякими способами, то здогадалися, що ODAC підтримує кілька способів організації зв'язку master/detail. Розглянемо їх докладніше (з прикладу демонстраційної бази, що ставиться разом із Ораклом).

Зазвичай зв'язок master/detail організується для таблиць, пов'язані лише на рівні СУБД ставленням foreign key/primary key. Для організації зв'язку master/detail нам знадобляться два компоненти TOraQuery та один компонент TDataSource (TOraDataSource): Примітка. За допомогою дизайнера форм можна створити зв'язок master/detail не написавши жодного рядка коду (. ), потрібно лише "кинути" на форму відповідні компоненти і налаштувати потрібні властивості. У гіршому випадку потрібно в коді відкрити у правильному порядку ці датасети.

Декілька важливих пояснень. Ім'я параметра у дочірньому запиті (detail датасет) має відповідати імені поля в основному запиті. Значення для другого запиту автоматично береться зполя основного запиту При скролінг основного датасета, дочірній запит автоматично буде виконуватися з потрібним параметром, тому якщо дочірній запит буде "важким", то буде спостерігатися деяка "загальмованість" інтерфейсу. При додаванні нового запису до дочірньої таблиці (запиту) у поле з foreign key автоматично вставляється значення primary key з поточного запису основної таблиці (запиту).

ODAC підтримує ще один спосіб організації master/detail з використанням властивостей MasterFields/DetailsFields: У другому випадку імена полів, якими встановлюється зв'язок, вказуються не в дочірньому запиті, а в спеціальних властивостях. Якщо Ви уважно читали попередній випуск, то могли б подумати, що дочірній запит повертатиме всі записи, а не лише ті, що нам потрібні. Однак, це не так. Під час виконання програми ODAC самостійно змінить запит SELECT * FROM Employee WHERE DepNo = :DepNo і буде працювати як у першому випадку.

Який варіант організації зв'язку master/detail використовувати – вирішувати Вам. Я через звичку використовую перший спосіб. У наступному випуску я продовжу розповідь про OraQuery.

З повагою, координатор розсилки Олексій aka Gelios.