Social Icons

.

понедельник, 30 августа 2010 г.

Использование курсоров в хранимых процедурах на TSQL

Задача:

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


 Концепция:

Перебираем строчки в цикле по одной и делаем необходимые преобразования.

Решение (пример):

Я не буду объяснять, что  это за функция, что она делает и с какими таблицами работает. По затронутой теме ценны семь нумерованных комментариев, которые показывают последовательность работы с курсором.
USE [SkiData]
GO
/****** Object:  StoredProcedure [dbo].[GenerateTicketNo]
Script Date: 08/30/2010 11:53:33 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
 
ALTER PROCEDURE  [dbo].[GenerateTicketNo]
 @nUid int 
AS
BEGIN
 SET NOCOUNT ON;
 
 DECLARE @nTicket int; SET @nTicket = 0;
 
 DECLARE @nNext int; SET @nNext = 0;
 SELECT @nNext = nUpidNext FROM UidList WHERE nIndex = @nUid
 IF @nNext IS NULL  SET @nNext = 0;
 
 DECLARE @nMessageId int; SET @nMessageId = 0;
 SELECT @nMessageId = nMessageId FROM guideMain WHERE nIndex = 1
 IF @nNext IS NULL  SET @nNext = 0;
 
 /*1. Декларируем курсор для исполнения конкретного запроса*/
 DECLARE theCursor CURSOR FOR SELECT nTicket FROM UidFrame  
 WHERE nUid = @nUid
 /*2. Открываем его (выполняем запрос)*/
 OPEN theCursor;
 
 WHILE 1=1 BEGIN
  /*3.Получаем "следующую" строку данных, и укладываем ее в 
  переменную. (тут только одна, но можно перечислить несколько
  через запятую)*/
  FETCH NEXT FROM theCursor INTO @nTicket;
  /*4. Проверяем, удалось ли нам получить строку*/
  IF @@FETCH_STATUS <> 0 BREAK;
 
  /*5. Работаем с полученными данными*/
  UPDATE UidFrame SET nUpid = @nNext, nMsg = @nMessageId 
  WHERE nUid = @nUid AND nTicket = @nTicket
 
  SET @nNext = @nNext + 1;
  SET @nMessageId = @nMessageId+1;
 END
 
 /*6. Закрываем курсор*/
 CLOSE theCursor;
 /*7. Убиваем курсор*/
 DEALLOCATE theCursor;
 
 UPDATE UidList  SET nUpidNext = @nNext WHERE nIndex = @nUid
 UPDATE guideMain SET nMessageId = @nMessageId WHERE nIndex = 1
END

Дополнительно

Комментариев нет:

Отправить комментарий

 

Так говорил Учитель:

У хорошо написанной программы есть свой собственный рай, у плохо написанной — свой собственный ад.

Russian Developer

Взгляд его светел, усилия праведны, старания бесплодны, дело безнадежно ...