Программирование баз данных MS SQL Server (1084479), страница 67
Текст из файла (страница 67)
Функция 1БИОЬЬ () принимает в качестве параметра переменную (о чем речь пойдет в главе 11) или выражение, а затем проверяет, не имеет ли этот параметр неопределенное значение. Если параметр действительно имеет )ч(1)Е1:значение, то функция 1БМОЬЬ () возвращает некоторое другое заранее заданное значение. Если же параметр функции имеет значение, отличное от ХОЬЬ, функция возвращает именно это значение. Синтаксис вызова функции 1БМОЬЬ () довольно простой: 1яхпьь(<ехргеяяЬоп го сяяг>, <гер1ясявепс ча1пе ье пп11>) Примеры результатов, полученных при вызове функции 1БМОЬЬ (), приведены в табл.
7.1. таблица 7.1. Примеры использования функции Езицьь ц Возвращаемое значение Выражение ТБИПЬЬ 1ЯХОЬЬ(НОЬЬ, 5) 15НОЬЬ(5, 15) 1БМОЬЬ(Муептпявнявя, О) янягя Муеп1пвпмя 15 МОЫ. 1ЯМОЬЬ(муСп1ивпмяве, О) ньеге МуСп1пвпмявя = 3 1БХОЬЬ(мусп1пвпмяве, О) ньеге МуСп1ивпмяве ='Ргег) Рягп1ег' Ргяд Рягвег Теперь рассмотрим, как можно применить эту функцию в данном примере запроса: ЯЕЬЕСТ сп.Спврапумаве, 1БХОЬЬ(САБТ ((ЯЕЬЕСТ М1Х(п.огг)егпясе) РКОМ Огг(егя о ХНЕРЕ о.Спяспвег10 = сп.спясовег10)АБ чагспаг), ' МЕЧЕН ОНОЕНЕО') АБ "Огс)яг Оаге" РНОМ Спяговегя сп В приведенных выше сокращенных результатах это не показано, но просмотр всего объема полученных данных позволяет обнаружить большое количество строк, содержащих )ч)1)Е1:значения в столбце Огс(ег Басе. С чем, по мнению читателя, это связано) Безусловно, причина появления )ч)1)Е(:значений состоит н том, что отсутствует строка в таблице Огг(егя, соответствующая строке таблицы СОЯСовегя, рассматриваемой как текущая (во внешнем запросе).
В связи с описанной ситуацией целесообразно немного отвлечься, чтобы рассмотреть чрезвычайно полезную функцию, позволяющую распознавать наличие )ч)1)Е(= значений, — 1БМОЬЬ () . 264 Глава 7 Перед этим неприемлемые результаты были получены в следующих двух строках: РЕяяв РаЬгьса Еоье . яаьсбцсваз я.я. НОЬЬ Рас1з зрес1а11Сез А после указанной доработки запроса формируются следующие, гораздо более полезные результаты: Рьяял Равсьса Епгег. яа1сньсваз я.я. МЕЧЕК ОКОЕКЕО Рагйз зресьа11ъез Обратите внимание на то, что для успешной )зеолизауии данного зап)зова пРишлось п)ллмлнить также фунну ию САЯТ П . Это потребовалось в связи с тем, что при выполнении )зоссиагяриволкого зап(зова возникают проблемы п(заведения типа и неявного п(зеоб)залезания Поскольку п)зи обработке первой страхи происходит воза)заел действительной даты, п(занимаетсяя зфедположекие, что отолбеу Огс) ех Оа Се относится к типу Оа С е Тц те.
А после того как впг)звые происходит замена ХПЕ значения строховьсм значением ИЕ'РЕК ОКОЕКЕО с помогцью функции ЕЯИОЬЬ, возникает ошибка, поскольку значение строки ИЕРЕЕ ОЕОЕКЕО невозможно п(зеобразовать в значение с типом данных Оа се Тцме. Рекомендуем читателю учесть возможность пУчгмекекия функции САЯТ П, поскольку она позволяет сп)завиться с небольшими сложностями, подобными описанной. Дополнительная информация о функции САЯТ () п(заведена ниже в данной главе. Таким образом, вы уже ознакомились со связанными подзапросами, которые предоставляют информацию и для конструкции Р)ЕЕКЕ, и для списка выборки.
При желании, в одном и том же запросе могут применяться любые комбинации подзапросов того и другого типа. Производные таблицы Иногда в процессе обработки данных возникают такие ситуации, когда необходимо обеспечить работу с результатами запроса, но для этого требуется применить такой способ доступа к результатам, который фактически не сводится ни к одному из тех разновидностей подзапросов, которые были описаны до сих пор.
В качестве примера можно указать такую ситуацию, что каждой строке в какой-то конкретной таблице может соответствовать несколько результатов, полученных с помощью подзапроса, и к этим результатам должна быть применена более сложная операция по сравнению с той, какая может быть предусмотрена в конструкции ЕИ. По существу, к этому сводятся в основном такие ситуации, в которых требуется использовать в подзапросе операцию ЯОЕИ.
Именно при таких обстоятельствах приходится прибегать к применению конструкции аз зг., менее широко распространенной по сравнению с другими, — производной таблицы. Производная таблица состоит из строк и столбцов результирующего набора некоторого запроса. (В конечном итоге результирующий набор обладает такими же свойствами, как и обычные таблицы, состоит из столбцов, строк, харак- Дополнительные сведения о запросах 265 теризуется применением определенных типов данных, поэтому вполне допускает использование в качестве таблицы.) Предположим, например, что требуется получить список заказчиков, заказавших определенный товар, скажем, шоколад, СЬосо1аде.
Решение этой задачи не представляет никакой сложности. Необходимый для этого запрос может выглядеть примерно таким образом: ЯЕЬЕСт с.спврапумаве ЯНОМ Спзтоветз Ая с ЯО1М Отдетз АЯ и ОН с.спзтоветгО = п.спзппветго ЯОРМ [Отдет Оетз11з) Ая од ОН п.отдетгп = од.о д го ЯО1М Ртодпстз Ая р ОМ пд.Ртодпст1О = р.ртпдпст1О ХНЕЕЕ р.Ртпдпспмаве = 'Спосп1аде' Итак, с первой задачей мы справились легко.
А теперь рассмотрим более сложную задачу. Предположим, что требуется получить список всех заказчиков, которые заказали не только товар, обозначенный как Спосо1аде, но и вегетарианский паштет, уед1е-Яртеад. Обратите внимание на то, что по условиям задачи требуется получить список заказчиков, заказавших оба этих товара. А в связи с решением этой задачи возникают сложности. Первой попыткой ее решения могло бы стать применение запроса с такой конструкцией: МНЕНЕ р.ртодпстмаве = 'СЬосо1аде' АНО р.Ртпдпстнаве = 'Чео1е-зртеад' Но подобный запрос является абсолютно неприемлемым, так как каждая строка содержит сведения только об одном товаре, поэтому таких строк, в которых были бы одновременно указаны названия товаров СЬосо1аде и Чед1е-яртеад, в базе данных нет. Это означает, что попытка выборки подобных строк окончится неудачей (и действительно, после вызова запроса на выполнение формируется результирующий набор, не содержащий строк).
Фактически для решения данной задачи необходимо соединить результаты запроса по поиску покупателей товара СЬосо1аде с результатами запроса по поиску покупателей товара уео1е-эртеад. А для соединения этих результатов, вполне очевидно, потребуется воспользоваться конструкциями, описанию которых посвящен настоящий раздел, — производными таблицами. Для создания производной таблицы необходимо выполнить два описанных ниже условия.
О Заключить в круглые скобки запрос, который вырабатывает необходимый ре. зультирующий набор. П Предусмотреть в запросе псевдоним для полученных результатов. Итак, синтаксис оператора, позволяющего решить поставленную задачу, должен выглядеть примерно таким образом: ЯЕЬЕСТ <зе1ест 11эт> Гном (<цвету тпат тетптпз а теоп1ат тези1сзес>) Ая <а1таз паве> ЮОХН <зове оппет Ьазе пт деттчед СаЬ1е> Воспользуемся этим замыслом для реализации поставленных требований, с учетом того, что необходимо также определить названия всех компаний, которые за- 266 Глава 7 казали и товар С))осо1абе, и товар )(едЬе-яргеаб.
Поэтому итоговый запрос должен выглядеть следующим образом: ЯЕЬЕСт Отзтгнот с.Сопряпунвве РВОМ Сияпожегв АЯ с З01Н (ЯЕЬЕСТ Сиясопег10 РВОМ Огбегв и Ю01Н [Огбег Оеьв11я) об ОИ о.огбег10 = об.Огбег10 З01Н Ргобисья р ОН об.ргобисс10 = р.ргобисс10 ИНЕВЕ Р.Ргобисьнвае = 'Сьосо1абе') АЯ яреп Он с.сиясопег10 = яреп.сияьоаег10 Т01Н (ЯЕЬЕСТ Сиясопег10 РВОМ Огбегя о З01Н [Огбег Оесаг1я) пб ОН о.огбег10 = об.огбег1О йОХН Ргобисся р ОН об.Ргобис110 = р.Ргобисп10 ИНЕВЕ Ргобисснапе = 'Уеяте-яргеаб') АЯ ярар ОК с.сиясопег10 = яряр.сияпопег10 Как оказалось, выполнение данного запроса приводит к получению сведений только об одном заказчике: Соарапунапе Егпяс Нвпбе1 (1 гпч(я) аттессеб) Чтобы проверить правильность полученных результатов, достаточно просто выполнить запросы, относящиеся к двум производным таблицам отдельно, а затем сравнить полученные результаты.