0

SQL Server 2016 accessible par ASP.NET MVC 4.6.2 Application webSQL Server Trigger - Empêcher la mise à jour de la ligne si la colonne IsLocked BIT est vrai

je Table "Bâtiment" et un bâtiment peut avoir plusieurs composants » ". Par exemple, Building1 a Component1 et Component2 ... etc

Il m'a été demandé de pouvoir verrouiller un bâtiment. Lock signifie qu'un composant ne peut plus être modifié (CREATE/UPDATE/DELETE). Eh bien, comme vous pouvez l'imaginer, c'est une application énorme et un composant peut être modifié dans 100+ endroits. Personne ne peut même répondre à la question: «Où dois-je tout verrouiller? Ma pensée est de verrouiller partout où je peux penser et puis comme un filet de sécurité créer un déclencheur SQL qui empêche toutes les modifications si la colonne sur la table de composants "IsLocked BIT" est vrai. Actuellement, la seule façon dont je sais si un composant est verrouillé est que la colonne IsLocked soit égale à true. Donc, je dis tout cela pour cela. Comment créer un déclencheur SQL Server qui empêche la modification d'une ligne de données si la ligne en cours de modification a la colonne IsLocked = 1?

Éditer 1 À mon avis, ce n'est pas un doublon. Utiliser au lieu de supprimer ou au lieu de ... ne fonctionnera pas pour moi. Si je fais le au lieu de ... alors à l'intérieur de cela, je devrai fournir une logique de validation. Je ne veux pas fournir de logique de validation. Je veux juste lancer une vérification avant d'insérer, mettre à jour, supprimer.

Edit 2 - Au lieu de mise à jour/Supprimer est le meilleur choix Si au lieu de ... est mon meilleur choix que quelqu'un peut réécrire ce que j'ai en utilisant le lieu de mise à jour/supprimer? Je ne sais pas comment le faire. Veuillez garder à l'esprit que les demandes proviendront d'une application Web. Je ne saurai pas s'ils mettent à jour une colonne ou l'entité entière ou ce qu'ils transmettront. Je sais que de la façon dont je l'ai écrite, elle va intercepter/mettre à jour/supprimer et l'empêcher si elle est verrouillée. S'il y a un meilleur moyen, veuillez l'écrire et expliquer pourquoi c'est mieux.

+0

'lieu de delete' déclencheur. C'est presque définitivement une question en double. – user1935361

+0

Copie possible de [empêcher la suppression d'un enregistrement spécifique] (http://stackoverflow.com/questions/4037243/preventing-a-specific-record-from-being-deleted) – user1935361

+0

Au lieu de mettre à jour/supprimer est votre meilleur choix . Bien sûr, vous devrez écrire la déclaration de mise à jour ou de suppression dans le déclencheur, mais cela ne devrait pas être beaucoup plus long que le code que vous avez maintenant. –

Répondre

0

Voici la solution que je suis venu avec:

ALTER TRIGGER [dbo].[PreventLockedModification] 
ON [dbo].[Component] 
FOR INSERT, UPDATE, DELETE 
AS 
BEGIN 

    SET NOCOUNT ON; 

    --DETERMINE INSERT(I) UPDATE(U) OR DELETE(D) 
---------------------------------------------------------------------------------------------------- 
    DECLARE @action as char(1); 

    SET @action = 'I'; -- Set Action to Insert by default. 
    IF EXISTS(SELECT * FROM DELETED) 
    BEGIN 
     SET @action = 
      CASE 
       WHEN EXISTS(SELECT * FROM INSERTED) THEN 'U' -- Set Action to Updated. 
       ELSE 'D' -- Set Action to Deleted.  
      END 
    END 
---------------------------------------------------------------------------------------------------- 

    DECLARE @ErrorMsg nvarchar(100) = 'This row is locked and cannot be updated'; 
    DECLARE @IsLocked bit; 
    DECLARE @BuildingId bigint; 
    DECLARE @UnitId bigint; 
    DECLARE @IsComplete_Building bit; 
    DECLARE @IsComplete_Unit bit; 

---------------------------------------------------------------------------------------------------- 
    IF @action = 'U' or @action = 'D' 
     BEGIN 
      SELECT @IsLocked = IsLocked FROM deleted; 
      IF @IsLocked = 1 
       BEGIN 
        RAISERROR (@ErrorMsg, 16, 1); 
        ROLLBACK TRANSACTION 
       END 
     END 
---------------------------------------------------------------------------------------------------- 
    ELSE IF @action = 'I' 
     BEGIN 
      SELECT @BuildingId = BuildingId FROM inserted; 
      SELECT @UnitId = UnitId FROM inserted; 

      SELECT @IsComplete_Building = IsComplete FROM Building WHERE BuildingId = @BuildingId 
      SELECT @IsComplete_Unit = IsComplete FROM Unit WHERE UnitId = @UnitId 

      IF @IsComplete_Building = 1 or @IsComplete_Unit = 1 
       BEGIN 
        RAISERROR (@ErrorMsg, 16, 1); 
        ROLLBACK TRANSACTION 
       END 
     END 
---------------------------------------------------------------------------------------------------- 



END