0

おそらく私は何かを見逃していますが、RAISERROR以下の s の重大度が 16 (ドキュメントによると) であっても、トランザクションはXACT_ABORT ON効果がないかのようにまだコミットされています。

CREATE PROCEDURE [ExploringGroups].[RemoveMember]
@groupId        uniqueidentifier,
@adminUsername  nvarchar(50),
@targetUsername nvarchar(50)
AS
SET XACT_ABORT ON

BEGIN TRANSACTION

DECLARE
    @adminUserId    uniqueidentifier = dbo.fn_userId(@adminUsername),
    @targetUserId   uniqueidentifier = dbo.fn_userId(@targetUsername)

IF @targetUserId IS NULL OR ExploringGroups.IsMember(@groupId, @targetUserId) = 0
    RAISERROR('Target user was not located', 16, 1)

IF ExploringGroups.IsInRole(@groupId, @adminUserId, 'adm') = 0
    RAISERROR('Specified user is not an administrator of this group', 16, 2)

IF @adminUserId = @targetUserId
    RAISERROR('You cannot remove yourself', 16, 3)

    -- statements below still execute and commit even though there was an error raised above
DELETE FROM ExploringGroups.MemberRole WHERE GroupId = @groupId AND UserId = @targetUserId
DELETE FROM ExploringGroups.Membership WHERE GroupId = @groupId AND UserId = @targetUserId

COMMIT

RETURN 0

通話中

exec exploringgroups.removemember '356048C5-BAB3-45C9-BE3C-A7227225DFDD', 'Crypton', 'Crypton'

プロデュース

Msg 50000、Level 16、State 2、Procedure RemoveMember、Line 20
指定されたユーザーはこのグループの管理者ではありません
Msg 50000、Level 16、State 3、Procedure RemoveMember、Line 24
自分自身を削除することはできません

XACT_ABORTに設定されている場合、トランザクション全体をロールバックすることになっていると思いましたONか?

4

2 に答える 2

1

RAISERROR アプローチではなく、「THROW」ステートメントを使用する必要があります。

BEGIN TRY および BEGIN CATCH を使用して、通常どおりにトランザクションをコミットするか、CATCH ブロックでロールバックします。

BEGIN TRY -- 挿入を実行するか、エラーをスローします -- トランザクションをコミットします END TRY BEGIN CATCH -- ロールバック END CATCH;

于 2014-05-01T17:58:38.580 に答える