Робота з автоінкрементальними (AutoInc) полями, DelphiSite
Найбільш читане
Робота з автоінкрементальними (AutoInc) полями
Робота з автоінкрементальним типом поля (Auto-increment, поле з автоприрощенням) У додатках Delphi, при використанні таблиць, що містять автоінкрементальні поля або поля, що автоматично збільшують будь-яким способом, невідомим додатком, своє значення можуть спостерігатися проблеми. Таблиці Paradox, InterBase, Sybase та Informix мають засоби автоматичної вставки та оновлення значень полів, без втручання сервісів та кінцевих додатків. Проте, не кожна операція з таблицею підтримується таким механізмом. Цей документ має продемонструвати основні методи роботи з такими типами полів у таблицях Paradox 5.0, Informix 5.x, MS/Sybase SQL Server 4.x, InterBase 4.0 та Local InterBase. У кожного типу таблиці за лаштунками працює власний механізм. Таблиці Paradox підтримують автоінкрементальний (Autoincrement) тип поля. Коли до таких таблиць додаються нові записи, Borland Database Engine визначає максимальне поточне значення цієї колонки, додає одиницю, і оновлює новий рядок з новим значенням. Для таблиць Informix ця поведінка передбачається специфічним типом Informix-поля, названого Serial. Колонки Serial відрізняються від автоприрощуються (Autoincrement) полів Paradox тим, що в таблицях Informix значення цього типу полів можуть бути змінені, тоді як у таблицях Paradox вони призначені лише для читання. Таблиці InterBase і MS/Sybase SQL Server не мають спеціального типу поля, що підтримує цю характеристику, але для виконання того ж завдання можна скористатися тригерами. Тригери є спеціалізованими процедурами, які знаходяться на сервері баз даних і автоматично виконуються ввідповідь на якусь подію, наприклад, додавання до таблиці, оновлення та видалення. Використання таблиць зі зв'язаними тригерами може бути особливо проблематичним, оскільки тригери здатні виконувати набагато більше функцій, ніж просто збільшувати значення колонки, що прирощується. Три функціональні області, які можуть впливати на цей тип поля у разі простої вставки, batchmoves і прив'язки (Linking) таблиці. Обробка Update та/або Append BatchMoves Таблиці Paradox Оскільки автоінкрементальний тип поля є типом тільки для читання, то спроба викликати операцію batchmove з даною колонкою в цільовій таблиці може призвести до помилки. Для того, щоб обійти це, властивість компонента TBatchMove Mappings повинна бути встановлена так, щоб поля вихідної таблиці відповідали полям цільової таблиці, за винятком автоінкрементальних полів. Таблиці Informix Групове переміщення рядків у таблицю Informix з колонками, що мають тип Serial, помилки не викликає. Тим не менш, повинні вас попередити про можливі проблеми, оскільки Serial-колонки мають можливість оновлення і часто використовуються як первинний ключ. Таблиці InterBase Таблиці MS/Sybase SQL Server Тригери в таблицях InterBase і SQL Server можуть відстежити будь-які неправильні зміни, зроблені в таблиці, але це залежить від установок самого тригера. Тут також вас необхідно попередити про можливі проблеми, оскільки колонки, що оновлюються тригером, можуть бути використані як первинний ключ. Прив'язування таблиць за допомогою MasterSource & MasterFields Таблиці Paradox Таблиці Informix Якщо властивості MasterFields і MasterSource використовуються для прив'язки таблиць з відносинами майстер-деталь і одне з полів у "деталь"-таблиці є автоінкрементальним абоSerial-полем, то відповідне поле в "майстер"-таблиці повинно мати тип Long Integer або бути Serial-полем. Якщо "майстер"-таблиця не є таблицею Paradox, то ключове поле "майстер"-таблиці може бути полем будь-якого типу, якого вона підтримує. Таблиці InterBase Таблиці MS/Sybase SQL Server Прив'язка з використанням даного типу таблиць не викликає проблем, якщо користуватися полями, що змінюються тригером. Єдина вимога полягає у зіставленні необхідних типів колонок обох таблиць. Проста вставка/оновлення (Inserts/Updates) Таблиці Paradox Оскільки автоінкрементальні поля Paradox мають атрибут тільки для читання, вони зазвичай не призначені для оновлення та вставки нових записів. Отже, властивість Required для field-компонентів, що базуються на автоінкрементальних полях, повинні завжди бути встановлені False. Це може бути виконано з Delphi за допомогою Fields Editor визначенням field-компонентів у режимі розробки) подвійне клацання на компоненті TQuery або TTable), або під час роботи програми за допомогою наступного коду:
Table1.Fields[0].Required := False; або
Таблиці Informix Хоча Serial-поля Informix і є оновлюваними, але якщо у них має бути використана характеристика автоприрощення, то властивість Required для field-компонентів, що базуються на такому полі, повинна бути встановлена False. Робіть так само, як це було описано для таблиць Paradox. Таблиці InterBase Таблиці MS/Sybase SQL Server Обробка вставки цих типів таблиць, що змінюються тригером, вимагає зробити кілька кроків. Додаткові кроки особливо необхідні в тому випадку, якщо вставка виконується за допомогою стандартних елементів керування для роботи з базами даних типу DBEdits або DBMemos. Вставлення рядків у змінені тригерами InterBase- та SQL Server таблиці може з достатньою ймовірністю викликати повідомлення про помилку 'Record/Key Deleted'. Це повідомлення про помилки з'являється, незважаючи на те, що таблиця правильно оновлюється на сервері. Це відбувається у разі, якщо: 1. Тригер оновлює первинний ключ. Помилка може виникнути не тільки при використанні тригера, але є найбільш ймовірною причиною помилки. 2a. Інші колонки таблиці мають пов'язані значення за промовчанням. Це виконується ПО УМОВЧЕННЯ у разі створення таблиці InterBase або процедурою sp_bindefault, що зберігається на сервері SQL Server. або 2b. При вставці нового рядка поновлюються поля, що мають тип Blob. або 2b. У таблиці InterBase визначені поля, що калькулюються. Основна причина цих помилок полягає в тому, що коли запис (або ідентифікаційний ключ) змінюється на сервері, BDE більше не має способів ідентифікувати запис для його повторного пошуку. Тобто запис більше не з'являється, як це було б, якби його "запостили", отже, BDE думатиме, що запис видалено (або змінено ключ). По-перше, field-компоненти змінюваних тригером полів повинні мати властивість Required, встановлену False. Робіть так само, як це було описано для таблиць Paradox. По-друге, щоб уникнути випадкових помилок, встановіть порядок таблиці за індексом, який не використовує поля, що оновлюються тригером. Це також не дозволить знову введений запис зникати відразу після його вставки. Нарешті, якщо умова 1, наведена вище, неможлива, але можливий настання подій 2a, 2b або 2c, то необхідно створити обробник події AfterPost компонента TTable як показано нижче:
procedure TForm1. Table1AfterPost (DataSet: TDataset);
МетодRefresh знову перечитує значення, змінені сервером. Якщо виконання умов 2a, 2b або 2c неможливе, таблиця могла б бути оновлена без елементів управління Delphi для роботи з базами даних. Це може бути виконано за допомогою компонента TQuery, що посилається на ту саму таблицю. Після того, як буде надіслано запит на оновлення, будь-які TTable-компоненти, які використовують ту саму таблицю, повинні бути оновлені (Refreshed).