РАБОТАЕМ С ДАННЫМИ | КОМПЬЮТЕРНАЯ ГАЗЕТА
Применение запросов-действий, или три молодца из ларца После наработки некоторых практических навыков работы с обычными запросами-выборками, или просто запросами, как их обычно именуют в простонародье, становится понятно, почему технология СУБД завоевала столь большую популярность за столь короткое время. Как бы там ни было, но в реальной жизни буквально каждый третий человек в той или иной степени нуждается в конкретной информации, являющейся лишь частью одного большого массива данных, и без механизма запросов ему просто не выжить. К примеру, куда удобнее просмотреть короткий список поездов, идущих в конкретный день в конкретный город, чем высматривать то же самое, но на огромном табло, где мелким шрифтом показаны все поезда всех направлений, проходящие через данную станцию. Как это делается, речь шла ранее, теперь давайте разберемся, каким образом в этот огромный перечень все эти данные попадают. (c) Компьютерная газета | Как известно, новые данные в таблицы, а значит и во всю базу, вносятся с клавиатуры, как правило, посредством заполнения соответствующих полей специально разработанных для этого форм. Указанный способ хорош буквально всем и применяется повсеместно, однако он не лишен и своих недостатков. Представим на время, что существует некое предприятие с целой сетью автономных филиалов, связанных с головным офисом бухгалтерской отчетностью и единым оптовым складом. Толковый ее руководитель, естественно, в первую очередь организует единую сквозную систему хозяйственной отчетности, при которой все филиалы, ежедневно или раз в неделю, по электронной почте, по Интернет или иным способом, сбрасывают в головную контору определенным образом оформленный результат, который помещается в общее хранилище. Тут и возникает одна "небольшая" проблема. Иным образом поступить нельзя, так как если каждая продажа, например пачки порошка в городе Гродно, непременно сопряжена с обращением к центральному хранилищу данных в Минске, то при качестве и скорости наших линий связи клиент раньше поседеет, чем дождется результата. С другой стороны, если полученные от всех активно работающих филиалов недельные отчеты сначала распечатать, а потом вручную заново ввести уже в минскую базу, то этот процесс не закончится никогда. К моменту окончания ввода данных за одну неделю в офис поступят данные за следующую, и вся прелесть от использования вычислительной техники будет потеряна. Единственным выходом из подобного замкнутого круга является автоматизация процедуры переноса данных из одного файла (базы данных, таблицы, запроса-выборки) в другой. Результатом такой автоматизации явилось создание специальной формы запросов, в результате выполнения которых СУБД определенным образом модифицирует исходные данные, хранящиеся в базе. Такие запросы называются запрос-действие, и с их помощью можно выполнить следующие задачи: - обновить группу записей (в результате выполнения запроса содержимое нескольких произвольных полей или даже целых записей может быть заменено новыми данными); - удалить группу записей (в результате выполнения запроса в автоматическом режиме из одной или нескольких таблиц базы данных можно удалить некоторое количество записей); - вставить данные из другой таблицы (например, буквально за несколько секунд перенести еженедельные отчеты филиалов в единую базу данных в головном офисе предприятия). В общем, как вы, надеюсь, уже поняли, запрос-действие является весьма удобным, полезным и чрезвычайно необходимым в хозяйстве рабочим инструментом любого человека, который тем или иным образом сталкивается с СУБД. Дело за малым - разобраться, как этот инструмент работает и как им пользоваться в повседневной жизни. Предлагаю рассмотреть один простой пример. Предположим, что исходя из каких-то своих загадочных умозаключений, таможня взяла да и увеличила на 10% пошлину за ввоз печатной продукции, к которой отнесла, в том числе, книги. Это привело к росту входной цены на ваш товар. Как правило, на складе вы держите только "растаможенные" книги, и указанная проблема несколько теряет актуальность, но, для чистоты эксперимента, предположим худшее. Произведения американского фантаста Хайнлайна расходятся настолько хорошо, что вы имеете большой и устойчивый спрос на них. Таким образом, можно несколько заработать еще и на том, что держать их запас в нерастаможенном состоянии и оплачивать таможенные сборы и пошлины по мере реализации. В таком случае, сразу, как только повышение пошлин станет свершившимся фактом, вы должны отразить это в своей базе данных. Если опираться только на тестовую базу данных (см. рис. 1), то проблема не стоит выеденного яйца. В продаже существуют лишь две книги указанного автора, и исправить их себестоимость вполне по силам в ручном режиме. Однако задача становится куда более устрашающей, если перечень наименований исчисляется несколькими тысячами, а список позиций, подлежащих корректуре, - несколькими сотнями. Тут на помощь приходит запрос-действие, при помощи которого процедура обновления полей займет едва ли более двух-трех минут. Создание, и тем более выполнение, любого запроса-действия в СУБД Microsoft Access всегда состоит из двух этапов. Сначала нужно создать запрос-выборку, а потом превратить его в запрос-действие и выполнить еще раз. Смысл в этом скрыт великий. Просмотрев результаты выборки, пользователь (разработчик) может даже чисто визуально убедиться в том, что все пройдет "как задумано" и что потом не придется срочно искать нашатырный спирт или валидол. Так как запрос-выборка не модифицирует данные, то в случае ошибки вам понадобится лишь заново переделать сам запрос, что особого труда не составляет. Итак, сначала делаем запрос-выборку. Эта процедура уже достаточно подробно рассматривалась ранее, а потому я скажу лишь о том, что в качестве критерия отбора следует использовать фамилию автора (в соответствии с условиями примера) (см. рис. 2). В результате получается временная таблица, в которой есть поле " Автор" и поле " Стоимость" (см. рис. 3). Первое поле нужно для идентификации записей, подлежащих модернизации, а второе содержит ту информацию, которую, собственно, и предстоит редактировать. Просмотрев итог выборки в режиме таблицы и убедившись, во-первых, что в выборку не попали книги других авторов, а во-вторых, что в выборку попали ВСЕ книги указанного автора и ничего не пропущено, можно изящным движением руки смело превратить запрос-выборку в запрос-действие и насладиться результатом. Эта процедура начинается с того, что, переведя запрос в режим конструктора и наведя маркер мыши в область с именами и обозначениями таблиц, нужно нажать правую клавишу мыши и в появившемся меню выбрать режим ТИП ЗАПРОСА, в раскрывающемся списке которого тут же выбрать ОБНОВЛЕНИЕ (см. рис. 4). Внешне ничего особенного не произойдет, но если присмотреться внимательнее к нижней части бланка запроса, то можно обнаружить в нем новую строку, которой ранее не было. Строка так и называется " Обновление". Все, что в ней записано, будет занесено в указанные поля вместо того, что в этих полях хранилось до выполнения запроса-обновления. В столбце " Стоимость" строки " Обновление" следует набрать или построить при помощи построителя выражений формулу [Стоимость] * 1,1 (см. рис. 5). Теперь, при выполнении данного запроса, СУБД самостоятельно поднимет себестоимость трудов Хайнлайна на требуемые 10%. Перед выполнением новый запрос следует сохранить, это заодно позволит проверить корректность введенных формул, ссылок и выражений, так как перед сохранением Microsoft Access делает ее автоматически и указывает на все имеющиеся ошибки, что позволяет безболезненно их исправить. Далее с полученным запросом следует обращаться как с ручной гранатой, которая, конечно, ручная, но все же требует к себе внимания и осторожности. Как только вы закроете запрос-обновление, он, выражаясь военными терминами, становится на боевой взвод. Это означает, что как только кто-то (например, оператор) или что-то (например, програм-мный модуль или макрос) данный запрос активизирует, то СУБД Microsoft Access автоматически выполнит обновление данных, как это заложено в инструкциях на бланке запроса. Касательно данного случая каждое выполнение запроса-обновления будет заканчиваться десятипроцентным ростом себестоимости книг Хайнлайна. Правда, СУБД сию тонкость тоже "понимает" и перед каждым запуском будет выдавать предупредительный диалог (см. рис. 6), предлагая дополнительно подтвердить либо опровергнуть свое распоряжение. Если вы нажмете " Да", то программа "проверит, что конкретно предстоит сделать", и выдаст еще одно, на этот раз последнее, предупреждение (см. рис. 7). В нем Microsoft Access еще раз напомнит, что некоторое (точнее, указанное конкретно) количество записей будет подвергнуто модернизации. Говорим " Да", ждем, когда запрос закончит работу (несколько секунд, в зависимости от объема исправлений), и открываем таблицу Литература. Одного взгляда достаточно, чтобы определить очевидное: запрос-обновление свою задачу выполнил на "отлично". Теперь несколько изменим условия тестовой задачи. Предположим, Microsoft Corporation выпустила новую версию текстового редактора Word, и она мгновенно завоевала бешеную популярность настолько прочно, что продавать книгу "MS Word для пользователей", освещающую прошлую версию программы, просто глупо. Следовательно, запись о ней нужно удалить и из магазинной базы данных. Как я уже говорил, теоретически, задача выполняется путем механического удаления строки из соответствующей таблицы. Однако подобное действие оставит большую кучу логического мусора. Примеров можно привести великое множество. Да и замучается оператор в ручном режиме удалять из таблицы пару сотен несмежных между собой строк. Держу пари: даже весьма внимательный и старательный человек в подобных условиях непременно что-нибудь упустит, а это совершенно недопустимо. Значительно удобнее воспользоваться специальной формой запроса-действия. Как и в прошлый раз, сначала следует создать запрос-выборку, только в этот раз целесообразно выбрать несколько иное сочетание полей, точнее, все поля, но в качестве условия отбора использовать конкретное наименование книги. Когда проверка покажет достижение удовлетворительного результата, то описанным выше способом превращаем запрос-выборку в запрос-удаление. В результате, в бланке запроса появляется поле (строка) " Условие". Так как вы уже все настроили, то имеет смысл переключить запрос в режим таблицы, убедиться, что "все ОК", сохранить и закрыть его. Все, запрос готов и поставлен на "боевой взвод". Как только вы отправите его на выполнение, после стандартного ритуала дополнительных предупреждений, аналогичного ситуации с запросом-обновлением, из таблицы "Литература" будет удалена запись о книге "MS Word для пользователей". Правда, следует помнить, что, в отличие от запроса-обновления, запрос-удаление является товаром одноразовым. Попытка его повторного выполнения приведет к тому, что Microsoft Access выдаст сообщение об ошибке, ибо в заданной таблице (в данном случае в таблице "Литература") больше нет записи о книге "MS Word для пользователей", а стало быть и удалять из нее нечего. Теперь мы подошли к тому, с чего начинали в самом начале. Каждую пятницу в конце дня каналы связи приносят вам массу стандартным образом сгенерированных Microsoft Access файлов, содержащих в себе типовые таблицы с данными о хозяйственной деятельности филиалов за отчетный период, которые нужно перебросить в точно такие же таблицы, но уже в центральной базе данных. Для этой цели в рамках Microsoft Access предусмотрен такой вид запроса, как запрос-добавление. Начало, естественно, полностью стандартно. Вы создаете типовой запрос-выборку и включаете в него все поля. В качестве примера я воспользовался таблицей "Литература". Перед удалением из нее записи о книге "MS Word для пользователей" я сделал копию этой таблицы, так что сейчас мы имеем две таблицы одинаковой структуры, содержащие однородные данные, то есть имеем ситуацию, описанную в нашем примере. Когда ваш запрос-выборка превратится в запрос-добавление, СУБД немедленно выведет на экран диалог для определения источника данных для их вставки в данную таблицу. Тут важно ничего не перепутать. Первоначальный запрос-выборку следует делать на основе той таблицы, ИЗ КОТОРОЙ будут вставляться данные, иначе результат вам, скорее всего, не понравится... В общем, как только вы попросите Microsoft Access изменить характер запроса, программа выведет на экран соответствующий диалог (см. рис. 8). Он работает следующим образом. По умолчанию подразумевается, что получатель данных расположен в этой же базе данных, и вам нужно всего лишь выбрать его название в выпадающем списке строки " Имя таблицы". Теоретически, оно, конечно, совсем неплохо, когда получатель информации расположен столь удобно, однако такое вовсе не обязательно. Достаточно переключить диалог в режим " В другой базе данных" и в появившемся окне указать путь к этой базе, Microsoft Access "все поймет" и обратится по указанному адресу. Нажатие экранной кнопки " ОК" приводит к двум последствиям: во-первых, в бланке запрос появляется новая строка " Добавление", а во-вторых, мастер автоматически заполнит ее наименованиями полей из таблицы-получателя данных. Ваша задача заключается в визуальном контроле корректности этой вставки. Когда наименование полей полностью совпадает, то ситуация вообще проста, как перпендикуляр, в противном случае лучше все-таки проверить. Далее опять "все как всегда", то есть переключаетесь в режим таблицы и удостоверяетесь, что будет вставлено именно то, что нужно, потом сохраняете запрос и, если нет возражений со стороны программы, закрываете его. Правда, у этого вида запроса есть одна тонкость, нередко приводящая к ошибкам. Дело в том, что вставка произойдет без сучка и задоринки только в том случае, если вставляемых данных в таблице-получателе не будет. Это вовсе не игра словами. Предположим, филиал просто сбрасывает вам копию всей своей базы и тем самым перекладывает на вас головную боль по сортировке данных. А сортировать их нужно, ибо в полученном массиве присутствуют как данные, внесенные в центральное хранилище в прошлый раз, так и новые, накопившиеся за последнюю неделю. Если не отделить предварительно "зерна от плевел", то при первом же столкновении с попыткой перенести уже имеющиеся данные, как говорится "возможны варианты". Теоретически, Microsoft Access просто игнорирует те записи, которые уже есть в таблице-получателе, и, тем самым, происходит автоматическая фильтрация информации, т.е. программа переносит только то, что в таблице-получателе отсутствует. Однако на практике чего только не происходит. Допустим, в структуре записи было некоторое поле, отражавшее текущее состояние продажи. Для филиала оно могло принимать одно из трех возможных состояний: заказано, выполняется, выполнено. Попадая в центральное хранилище, заказы, которые выполнены, могут также находится в состоянии "обработано службой анализа" и "перемещено в архив". В центральном хранилище подобное изменение содержимого поля производится по мере обработки информации соответствующими запросами автоматически. Таким образом, на момент добавления может случиться, что одна и та же запись о конкретной продаже в центральном хранилище помещена в архив, а в филиале числится всего лишь как законченная. При добавлении данных мне довелось наблюдать ситуацию, когда Microsoft Access на этом основании заново перенес одну и ту же запись в центральное хранилище, которое, в свою очередь, приняло ее как новую со всеми вытекающими негативными последствиями. Конечно, в теории считается, что при сбросе данных в центр база данных филиала должна исключать их из своего ре-естра, но это опять же в теории. На практике бывает всякое. К примеру, если филиал большой сам по себе и ведет активную хозяйственную деятельность, то ему самому понадобится архивная информация для проведения анализа на местном уровне, и руководителю филиала, вероятнее всего, перспектива каждый раз обращаться к центральной базе вовсе не придется по вкусу. Следовательно, во избежание недоразумений, имеет смысл перед вставкой данных сначала произвести их селекцию на предмет удаления записей, потерявших актуальность для центральной базы данных. Ну, а потом опять все как всегда. Перед выполнением запрос-добавление проанализирует обе таблицы и предупредит, что он, во-первых, намерен модифицировать данные таблицы, а во-вторых, собирается перебросить такое-то количество записей "из точки А в точку Б". Если вы согласны с обоими утверждениями, то оба раза нажмите " ОК" и полюбуйтесь результатом. Кстати говоря, если в каком-нибудь поле бланка запроса вы зададите конкретное условие, то СУБД переместит не все записи источника, а лишь те, которые данному условию соответствуют. Словом, красота! Полагаю, вы уже почувствовали: когда компьютер работает за вас, это весьма и весьма приятно. Так давайте же будем организовывать свою работу таким образом, чтобы на вас ложилась функция "думать", а на компьютер - "делать". Александр Запольскис E-mail: leshy@nestor.minsk.by