在sql server中使用而不是触发器更新记录

时间:2013-04-25 08:08:50

标签: sql-server sql-server-2005 triggers

我在sql server 2005中有触发器 检查重复记录然后更新记录。

USE [CheckeCon]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[tgUserRoleExistForUpdate] ON [dbo].[Sec_UserRoles]
INSTEAD OF Update
AS
declare @UserRoleId int, @UserId int,@RoleId int, @FromDate datetime,@ToDate datetime,@CntlCreatedBy nvarchar,@CntlModifiedAt nvarchar,@CntlCurLockNo smallint;
select @UserRoleId=i.UserRoleId from inserted i;
select @UserId=i.UserId from inserted i;
select @RoleId=i.RoleId from inserted i;
select @FromDate=i.FromDate from inserted i;
select @ToDate=i.ToDate from inserted i;
select @CntlCreatedBy=i.CntlCreatedBy from inserted i;
select @CntlModifiedAt=i.CntlModifiedAt from inserted i;
select @CntlCurLockNo=i.CntlCurLockNo from inserted i;
BEGIN
-- BEGIN TRAN
IF NOT EXISTS
(
    SELECT  *
    FROM    Sec_UserRoles SEUR
    JOIN    inserted i ON  
            SEUR.RoleId =  i.RoleId
    AND     SEUR.UserId = i.UserId
    Where i.FromDate BETWEEN SEUR.FromDate AND SEUR.ToDate
)
Update Sec_UserRoles Set UserId = @UserId,RoleId = @RoleId,FromDate = @FromDate,ToDate = @ToDate,
        CntlCreatedBy = @CntlCreatedBy,CntlModifiedAt = @CntlModifiedAt,CntlCurLockNo = @CntlCurLockNo Where  UserRoleId = @UserRoleId 
--Commit;
Else
    RAISERROR('User Role Association Already Present',15,1);
   --ROLLBACK; 
End

但问题是它无法更新记录只在触发器中给出的引发错误。 如何使用触发器更新记录?

先谢谢。

1 个答案:

答案 0 :(得分:0)

这可能对你有所帮助 -

ALTER TRIGGER [dbo].[tgUserRoleExistForUpdate] 

    ON [dbo].[Sec_UserRoles]
    INSTEAD OF UPDATE

AS BEGIN

    IF NOT EXISTS(
        SELECT 1
        FROM INSERTED
    ) RAISERROR('NO ROW IN INSERTED', 16, 1)

    SET NOCOUNT ON;
    SET XACT_ABORT ON;

    DECLARE 
          @UserRoleId INT
        , @UserId INT
        , @RoleId INT
        , @FromDate DATETIME
        , @ToDate DATETIME
        , @CntlCreatedBy NVARCHAR(MAX)
        , @CntlModifiedAt NVARCHAR(MAX)
        , @CntlCurLockNo SMALLINT

    DECLARE cur CURSOR LOCAL READ_ONLY FAST_FORWARD FOR
        SELECT 
              i.UserRoleId
            , i.UserId
            , i.RoleId
            , i.FromDate
            , i.ToDate
            , i.CntlCreatedBy
            , i.CntlModifiedAt
            , i.CntlCurLockNo 
        FROM INSERTED i

    OPEN cur

    FETCH NEXT FROM cur INTO
          @UserRoleId
        , @UserId
        , @RoleId
        , @FromDate
        , @ToDate
        , @CntlCreatedBy
        , @CntlModifiedAt
        , @CntlCurLockNo

    WHILE @@FETCH_STATUS = 0
    BEGIN

        IF NOT EXISTS(
            SELECT 1
            FROM dbo.Sec_UserRoles s
            WHERE @FromDate BETWEEN s.FromDate AND s.ToDate
                AND s.RoleId = @RoleId
                AND s.UserId = @UserId
                --AND s.UserRoleId = @UserRoleId 
        )
        BEGIN

            UPDATE dbo.Sec_UserRoles 
            SET 
                  UserId = @UserId
                , RoleId = @RoleId
                , FromDate = @FromDate
                , ToDate = @ToDate
                , CntlCreatedBy = @CntlCreatedBy
                , CntlModifiedAt = @CntlModifiedAt
                , CntlCurLockNo = @CntlCurLockNo 
            WHERE UserRoleId = @UserRoleId 

        END
        ELSE BEGIN

             RAISERROR('User Role Association Already Present', 0, 1) -- 15      

        END

        FETCH NEXT FROM cur INTO
              @UserRoleId
            , @UserId
            , @RoleId
            , @FromDate
            , @ToDate
            , @CntlCreatedBy
            , @CntlModifiedAt
            , @CntlCurLockNo

    END

    CLOSE cur
    DEALLOCATE cur

END