Главная » Microsoft SQL Server, Базы данных » Пример денормализации списка

0

Второй пример курсора в действии решает задачу денормализации списка. Нам требуется получить из дат туров Outer Banks Lighthouses разделенный запятыми список значений в виде одной строки.

Курсор проходит по всем датам туров, при этом в цикле WHILE все даты добавляются в локальную переменную @EventDates. Битовая локальная переменная @SemiColon определяет, нужен ли между датами разделитель в виде точки с запятой. В конце пакета инструкция SELECT возвращает денормализованный список дат.

USE СНА2 DECLARE

@EventDates VARCHAR(1024),

@EventDate DATETIME,

©Semicolon BIT SET @Semicoion = 0 SET @EventDates = ”

DECLARE cEvent CURSOR FAST_FORWARD FOR SELECT DateBegin FROM Event JOIN Tour

ON Event.TourlD = Tour.TourlD WHERE Tour.[Name] = ‘Outer Banks Lighthouses’

OPEN cEvent

FETCH cEvent INTO @EventDate – Подготовка курсора WHILE @@Fetch_Status = 0 BEGIN

IF @Semicolon = 1 SET @EventDates

= @EventDates + ‘ ; ‘

+ Convert(VARCHAR(15), @EventDate, 107 )

ELSE

BEGIN

SET ©EventDates

= Convert(VARCHAR(15), ©EventDate,107 )

SET @SEMICOLON = 1 END

FETCH cEvent INTO @EventDate – к следующей строке END

CLOSE cEvent DEALLOCATE cEvent

SELECT @EventDates

Будет получен следующий результат:

Feb 02, 2001; Jun Об, 2001; Jul 03, 2001; Aug 17, 2001;

Oct 03, 2001; Nov 16, 2001

Курсор с легкостью справился с задачей денормализации списка, и в будущем он может оказаться вам полезным. В то же время пакетное решение, использующее технологию переменной со множеством присвоений и продемонстрированное в следующем примере, работает в десяток раз быстрее и может быть использовано для более интенсивных задач.

Дополнительная Подробно о переменных с множеством присвоений см. в главе 18.

информация

В предлагаемом примере внутренний подзапрос возвращает список внешнему запросу, который, в свою очередь, добавляет каждый полученный результат в переменную @EventDates:

USE СНА2 DECLARE

@EventDates VARCHAR(1024)

SET @EventDates = ‘1

SELECT @EventDates = @EventDates

+ CONVERT(VARCHAR(15), a.d,107 ) + ‘;’

FROM (select DateBegin as [d] from Event join Tour

on Event.TourlD = Tour.TourlD

WHERE Tour.[Name] = ‘Outer Banks Lighthouses’) as a SELECT Left(@EventDates, Len(@EventDates)-1)

AS ‘Outer Banks Lighthouses Events’

Будет получен следующий результат:

Outer Banks Lighthouses Events

Feb 02, 2001; Jun 06, 2001; Jul 03, 2001; Aug 17, 2001;

Oct 03, 2001; Nov 16, 2001

Резюме

Когда оптимизация увеличивает производительность в десятки раз (от часов выполнения — в минуты, от минут — в секунды), тогда выполненная работа приносит удовлетворение. Не существует лучшего способа оптимизации хранимой процедуры, чем заменить ненужный курсор. Если вы ищете какой-то очень низко производительный продукт, тогда курсор — именно то, что вам нужно.

Разрешите процитировать моего друга Билла Вона: “Курсор придумал дьявол!” К этому мне нечего добавить. Любой курсор работает до безумия медленно. Ненужные курсоры входят в мой список пяти самых важных проблем производительности SQL Server. Лучший способ настроить курсор — это полностью заменить его элегантным пакетным запросом.

В следующей главе мы возьмем на вооружение все, о чем узнали в предыдущих главах, и будем встраивать пакеты в хранимые процедуры.

Источник: Нильсен, Пол. Microsoft SQL Server 2005. Библия пользователя. : Пер. с англ. — М. : ООО “И.Д. Вильямс”, 2008. — 1232 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии