Триггер SQL - конвертировать курсор с помощью заданной операции - PullRequest
0 голосов
/ 27 октября 2011

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

CREATE Trigger DataUpdate ON [Data]
    FOR UPDATE
    AS
      SET NOCOUNT ON
    BEGIN
       declare @Id int
       declare cur cursor for select DataId from Deleted
       open cur
       fetch next from c into @Id
       while @@FETCH_STATUS = 0
          begin
            if 
               UPDATE(ID) and
               UPDATE(Title) or
               UPDATE(Description)             
             BEGIN
                update Data 
                set ModDate = getdate()
                where ID = @Id
             END
            fetch next from c into @Id
          end
       close cur
       deallocate cur
    end

И еще один триггер

CREATE  TRIGGER DataAudit
      ON [Data] FOR UPDATE
      AS

      SET NOCOUNT ON

    IF UPDATE(ModDate)
         BEGIN
           SET NOCOUNT ON
           DECLARE @ParentId INT
           DECLARE @ChildId INT
           DECLARE @Export BIT

           DECLARE cursorInserted CURSOR FOR
              select ParentID, ChildID, Export from INSERTED

           OPEN  cursorInserted 

           Fetch next from cursorInserted into @ParentId, @ChildId, @Export

           WHILE @@FETCH_STATUS = 0
           BEGIN             
               DECLARE @brief BIT

               DECLARE cursorBriefcase CURSOR FOR
                select ShowExport
                  from Sites 
              where SiteID in (select ds.siteid from DataSiteIDs as ds where ChildID = @ChildId)   

               OPEN cursorBriefcase
                 -- Perform the first fetch.
                 FETCH NEXT FROM cursorBriefcase INTO @brief

                 -- Check @@FETCH_STATUS to see if there are any more rows to fetch.
                 WHILE @@FETCH_STATUS = 0 and @brief = 0
                   BEGIN
                      FETCH NEXT FROM cursorBriefcase INTO @brief
                   END
                 CLOSE cursorBriefcase
                 DEALLOCATE cursorBriefcase

             IF @brief = 0 and 
                @Export = 1   and 
                ((SELECT Distinct ParentID FROM Sites Where ParentID = @ParentId AND (TemplateID = 5 OR TemplateParams = 1) ) > 0) and 
                ((Select Distinct ParentID From SubUserGroupIDs Where ParentID = @ParentId) > 0)
             BEGIN
                -- Populate the SubAuditItems table with rows on hold
                INSERT INTO SubAuditItems (ChildID, ParentID, RecordDate, Type, FromTable)
                VALUES (@ChildId, @ParentId,  GETDATE(), 'MOD', 'Data')
             END

           Fetch next from cursorInserted into @ParentId, @ChildId, @Export
           END
           CLOSE cursorInserted
           DEALLOCATE cursorInserted    

        END

Ответы [ 2 ]

0 голосов
/ 27 октября 2011

Это должно относиться к телу первого триггера:

UPDATE d                 
 SET ModDate = getdate()
 FROM inserted i
 JOIN data d ON i.id = d.ID
 JOIN deleted del ON i.id = del.id
 WHERE 
   (i.Id <> del.id)
 OR
   (i.title <> del.title)
 OR
   (i.description <> del.description)

Если бы я правильно интерпретировал ваш второй пример, тело триггера было бы примерно таким:

 INSERT INTO SubAuditItems (ChildID, ParentID, RecordDate, Type, FromTable)  
 SELECT i.ChildID,i.ParentID, GETDATE(), 'MOD', 'Data' 
 FROM INSERTED 
 JOIN DataSiteIDs s ON ds.childid = i.childid
 JOIN Sites s ON ds.siteid = s.siteid
 WHERE i.Export = 1 
0 голосов
/ 27 октября 2011

@ Юсуф: Не могли бы вы дать нам немного больше деталей?чего ты хочешь добиться?если вы хотите сохранить записи, удаленные из таблицы, вы можете сделать это следующим образом:

CREATETRIGGER [dbo].[UpdateCustomerHistory]
    ON [dbo].[tblCustomers]
AFTER DELETE
AS 

---------------------------------------------------
-- Insert the deleted Record in History
---------------------------------------------------
INSERT INTO tblCustomersHistory
(
    CustomerId, Name, DateCreated
)
------ Get deleted row
SELECT  CustomerId, Name, GETDATE()
FROM    DELETED
...