|
Программирование >> Программирование баз данных
Ознакомившись с таким предложением по организации обработки данных, специалисты из отдела маркетинга решили проверить, какие результаты будут получены после повышения цен на 10%, поэтому в оператор CASE было включено выражение, обеспечивающее прибавление к стоимости 10%-ной наценки, и в конечном итоге после проведения небольшого дополнительного анализа был составлен сценарий, позволяющий решить поставленную задачу по округлению цен: USE AdventureWorks GO /* Объявления всех переменных, необходимых для хранения нормативных данных, ** сосредоточены в одном месте. Это позволяет упростить в дальнейшем ** корректировку запроса */ DECLARE ©Markup money DECLARE ©Multiplier money SELECT ©Markup = .10 -- Переменной ©Markup присваивается -- значение наценки. SELECT ©Multiplier = ©Markup +1 -- Необходимо определить конечную цену, -- а не величину повышения, поэтому к наценке прибавляется 1 /* Выполнение запроса для проверки полученных результатов. Необходимо отметить, ** что в данном случае в целях упрощения обработка ограничивается десятью ** максимальными значениями. Но на практике этого не следует делать. В крайнем ** случае можно применить более сложную конструкцию WHERE для повышения цен на ** товары определенной категории SELECT TOP 10 ProductID, Name, ListPrice, ListPrice * ©Multiplier AS Marked Up Price , New Price = CASE WHEN FLOOR(ListPrice * ©Multiplier + .24) > FLOOR(ListPrice * ©Multiplier) THEN FLOOR(ListPrice * ©Multiplier) + .95 WHEN FLOOR(ListPrice * ©Multiplier + .5) > FLOOR(ListPrice * ©Multiplier) THEN FLOOR(ListPrice * ©Multiplier) + .75 ELSE FLOOR(ListPrice * ©Multiplier) + .49 FROM Product ion.Product WHERE ProductID % 10 = 0 -- Эта конструкция выполняет в рассматриваемом операторе -- лишь вспомогательную роль ORDER BY ProductID DESC В этом примере используется весьма простая функция FLOOR, которая принимает переданное ей дробное значение и округляет его в меньшую сторону до ближайшего целого числа. Опытным разработчикам часто приходится сталкиваться с тем, что заказчики не всегда могут сразу предусмотреть все необходимые проверки; это особенно характерно для специалистов в области маркетинга или торговли. В этом нет ничего предосудительного, ведь они гораздо лучше разбираются в своей работе, чем в программировании. Но в конечном итоге обнаруживается, что после проведения одной проверки требуется еще одна, которая не предусматривалась ранее. Зная об этом, автор проявил предусмотрительность и учел такую возможность в своем сценарии; теперь, если окажется, что нужно проверить работу сценария на примере 15%-ной наценки, то достаточно будет изменить значение, применяемое для инициализации переменной ©Markup. Но все же на этот раз рассмотрим, какие результаты будут получены при использовании 10%-ной наценки:
(10 row(s) affected) Анализ этих результатов показывает, что они полностью соответствуют предъявленным требованиям. Более того, для получения этих данных не пришлось применять курсор. Формирование циклов с помощью оператора while Оператор WHILE в языке SQL действует во многом так же, как и в других языках, с которыми обьшно приходится работать профаммисту. По сути в этом операторе до начала каждого прохода по циклу проверяется некоторое условие. Если перед очередным проходом по циклу проверка условия приводит к получению значения TRUE, то осуш;е-ствляется проход по циклу, в противном случае вьшолнение оператора завершается. Для этого применяется следующий синтаксис: WHILE <Воо1еап expression> <sql statement> [BEGIN <statement block> [BREAK] <sql statement> <statement block> [CONTINUE] END] Безусловно, с помощью оператора WHILE можно обеспечить вьшолнение в цикле только одного оператора (по аналогии с тем, как обычно используется оператор IF), но на практике конструкции WHILE, за которыми не следует блок BEGIN. . . END, соответствующий полному формату оператора, встречаются редко. Оператор BREAK позволяет выйти из цикла, не ожидая того, как будет выполнен проход до конца цикла и произойдет повторная проверка условного выражения. Разумеется, автор - ш первый, кто начал настаивать на этом, но использование оператора BREAK обычно рассматривается как признак плохого стиля программирования, о чем говорят даже классические учебники. Я также всегда отстаиваю эту точку зрения. Действительно, следует избегать использования операторов BREAK при любой возможности. Чаще всего на практике удается обойтись без операторов BREAK, поменяв местами несколько групп операторов и добившись тех же результатов. При этом обычно достигается также еще одно преимущество - повышение удобства кода для чтения. Дело в том, что следить за работой циклической структуры (или даже, вообще говоря, любой программной структуры) намного легче, если в ней имеется единственная точка входа и единственная точка выхода. А если используется оператор BREAK, такой принцип организации кода нарушается. Но несмотря на сказанное, иногда действительно структура кода становится хуже после его переформатирования в целях исключения оператора BREAK. Кроме того, мне иногда приходилось сталкиваться с тем, что программисты были даже готовы использовать код, обладающий гораздо более низким быстродействием, лишь бы не применять оператор BREAK. Но это, безусловно, не рекомендуется. Оператор CONTINUE в определенном смысле является полностью противоположным оператору BREAK. Кратко можно описать действие оператора CONTINUE так, что он обеспечивает переход в начало цикла WHILE. Сразу после обнаружения оператора CONTINUE в цикле, независимо от того, где он находится, происходит переход в начало цикла и повторное вычисление условного выражения (а если значение этого выражения больше не равно TRUE, осуществляется выход из цикла). Рассмотрим небольшой пример, чтобы ознакомиться с тем, как работает цикл WHILE. 1Сак уже было сказано выше, цикл WHILE редко применяется не в сочетании с курсором, поэтому автору припыось поневоле составить довольно надуманный пример. В данном случае создается нечто вроде процесса мониторинга. Для этого используются цикл WHILE и оператор WAITFOR (более подробное описание оператора WAITFOR приведено в следующем разделе). В данном примере создается процедура автоматического обновления статистических данных один раз в сутки: WHILE 1=1 BEGIN WAITFOR TIME 01:00 EXEC sp updatestats RAISERROR(Statistics Updated for Database, 1, 1) WITH LOG С помощью этой процедуры через каждые сутки в один и тот же час ночи обновляются статистические данные по каждой таблице в базе данных и журнальная запись с информацией об этом факте вносится в журнал SQL Server и в журнал приложений системы Windows. Чтобы убедиться в том, что приведенный здесь сценарий действует правильно, оставьте его работать на ночь, а утром проверьте журналы. Следует отметить, чтю при обычных обстоятельствах планирование заданий по принципу использования подобного бесконечного цикла не рекомендуется. Если есть необходимость в том, чтобы какой-то сценарий вызывался на выполнение через каждые сутки, установите задание с помощью программы Management Studio. Этю позволяет не только избавиться от необходимости поддерживать постоянно открытым одно из соединений (с чем связано выполнение приведенного выше примера), но и получить возможность предусмотреть выполнение последующих действий с учетам успешного или неудачного завершения сценария. Кроме тюго, можно организовать отправку сообщений по электронной почте или по сети, указывая в них информацию о состоянии завершения сценария. Оператор waitfor в процессе работы часто возникают такие ситуации, что некоторое действие нежелательно или невозможно выполнить прямо сейчас, но не хочется также самому ждать, когда наступит время, подходящее для его выполнения.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |