|
Программирование >> Проектирование баз данных
Pending Orders CustBrnel lb Custorrip Expected Ship 6Klt- Puc 116 Экранная форма, представляющая совокупность заказов Вероятно, первое, что приходит вам в голову (особенно если вы такой же старый Forms-хакер, как мы), - это мысль реализовать эти функциональные возможности как триггер POST-QUERY: POST-OUERY SELECT cus.name INTO :ord.cus name FROM customers cus WHERE cus.id = :ord.cus id; При этом производится простой и высокоэффективный индексный поиск, однако он осуществляется один раз для каждой отображаемой в форме строки. Таким образом, в этом простом случае придется выполнять одну дополнительную операцию обмена сообщениями с сервером на каждую строку многострочной формы лищь для того, чтобы получить имя покупателя Последствия этого гораздо серьезнее, чем может показаться на первый взгляд, поскольку в Oracle Forms интенсивно используется массивная выборка, позволяющая выбрать все строки для заполнегшя формы за одно обращение. Таким образом, если в форме необходимо отобразить 10 строк, то нащ простой триггер может увеличить трафик сообщений с одной пары сообщений до одиннадцати. Пр1шсчание Здесь предполагается, что десять строк выбирается и десять отображается По умолчанию Oracle Forms выбирает на одну строку больще, чем может быть отображено в блоке формы. Это делается для более эффективного использования массивного интерфейса и для того, чтобы корректно показать, есть ли дополнительные строки. Добиться того, чтобы выборка всех данных для множества строк вновь осуществлялась за одну операцию обмена с сервером, можно так- необходимо определить представление и построить форму на базе представления, а не на базе таблицы ORDERS. В этом представлении будет выполняться соединение таблиц CUSTOMERS и ORDERS, и оно будет определено следующим образом: create or replace view v orders { Id , cus id , cus name , date taken , pending reason ) as select ord.id , ord.cus id , CUS.name , ord.date taken , ord.pending reason from orders ord , customers cus Where ord.cus id = cus.id; Столбец с именем клиента, CUSNAME, теперь является базовым полем формы, и сервер может передать клиенту эти данные за одну операцию выборки. Однако при этом возникает ряд проблем, которые связаны с эффективностью выполнения запросов и обновляемыми представлениями. Наша позиция по каждому из них зависит от используемой версии - как вы, наверно, догадались, чем новее версия, тем менее серьезна проблема. Во всех версиях Oracle до 7.3 представления, которые содержат соединения, не могут быть объектом DML-операций. Это означает, что операции INSERT, UPDATE и DELETE для них не разрешаются. Версия 7.3 поддерживает обновляемые представления, хотя, как следует ожидать, и здесь существует ряд ограничений. В любом представлении обновляемые столбцы должны принадлежать одной таблице, и эта таблица должна быть защищена по ключу {key preserved). В самом простом случае это означает, что ключ (ключи), по которому выполняется соединение, обновлять нельзя. Пока вы не станете работать с версией 7.3 (или более новой), вам придется программировать или генерировать триггеры ON-INSERT, ON-UPDATE и ON-DELETE в экранной форме для того, чтобы выполнить обновление через блок, построенный на представлении, содержащем соединение, или фактически на любом необновляемом представлении. Эти триггеры, которые, как правило, создать очень легко, просто явно выдают DML-операции для базовых таблиц представления. В нашем примере это Почти наверняка будет таблица ORDERS, так как совершенно невероятно. Что мы будем использовать многострочный блок на базе таблицы ORDERS для корректировки имен покупателей. Предупреждение Эти явные ОК-трипгеры будут, конечно, нормально работать даже после перехода на версию 7.3, независимо от того, окажется представление обновляемым или нет. Однако здесь просматривается некая тяжеловесность, потому что форма (или, точнее, блок) теперь зависит от определения представления. Если по какой-то причине вы переопределили представление V ORDERS для выбора данных из таблицы ORDERS2 и не переписали триггеры в Forms, то эти триггеры попытаются обновить не ту таблицу. В лучшем случае вы отделаетесь ошибкой. Если же вам не повезет, то обновление будет выполнено не в той таблице, что, конечно, весьма неприятно. Операция UPDATE или DELETE, вероятно, выполнена не будет, поскольку она ссылается на целевую строку при помощи идентификатора строки (ссьжка по идентификатору строки - стандартный метод для Forms-операций UPDATE и DELETE в строках базовой таблицы), но операция INSERT почти наверняка будет выполнена успешно! Оптимизация представлений Вопросы оптимизации выполнения запросов более проблематичны. Для большинства сложных многострочных блоков должен выполняться поиск не в одной таблице, а в нескольких. Часто бывает, что внешний ключ допускает неопределенные значения (т.е. эта связь не обязательна), поэтому в таком представлении должно осуществляться внешнее соединение. Первоначальная реакция как разработчика, так и пользователя на блоки, построенные на представлении, почти всегда положительна. Это объясняется тем, что они могут использовать любое из полей как основу для запроса и это устраняет традиционные проблемы, связанные с запросами к небазовым таблицам . К сожалению, хотя это решение богато функциональными возможностями и создает минимальный трафик сообщений, оно может серьезно увеличить нагрузку на сервер и время ответа. В качестве примера рассмотрим простое представление, определение которого приведено ниже. Чтобы пример был короче, мы опустили некоторые столбцы, которые читатель рассчитывал увидеть в таблице ORDERS. Однако здесь выполняется соединение по схеме звезда и продемонстрировано использование внешних соединений для обработки кодовых полей, значения которых могут быть неопределенными. CREATE OR REPLACE VIEW v orders ( id , settlement currency , quotation currency , sales office , cus tomer name ) AS SELECT ord.id , cel.name
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |