2010-12-15 183 views

Répondre

3

Voici un exemple d'utilisation FOR SUPPRIMER déclencheur pour empêcher la suppression d'une ligne lorsqu'une certaine condition est satisfaite:

CREATE TRIGGER KeepImportantRow ON MyTable 
    FOR DELETE 
AS BEGIN 
    -- This next line assumes that your important table has a 
    -- column called id, and your important row has an id of 0. 
    -- Adjust accordingly for your situation. 
    IF DELETED.id = 0 BEGIN 
     RAISERROR('Cannot delete important row!', 16, 1) 
     ROLLBACK TRAN 
    END 
END 
+0

Ce n'est pas une faute de frappe, la fonction est vraiment appelée RAISERROR (un E)! Consultez la documentation à http://msdn.microsoft.com/en-us/library/ms178592.aspx qui explique également les autres paramètres (gravité, 0-25 et état, 0-255). – thelem

1

Vous pouvez le faire de plusieurs façons, bien que cela dépende de la situation.

Si la table ne contient que cette ligne, n'accordez pas de privilège de suppression/tronquer.

Si la table contient également d'autres lignes, vous pouvez utiliser un déclencheur avant la suppression. Un problème que vous aurez est que quelqu'un avec DBA/SA accès à la base de données, peut contourner tout ce que vous mettez, si elles le désirent, alors qu'est-ce que vous essayez de protéger contre, utilisateur occasionnel, ou n'importe qui.

+0

Oui ce tableau a d'autres lignes aussi bien, un déclencheur sonne comme il pourrait être seul moyen d'aller faire appliquer cela au niveau de la base de données. – BrooklynDev

3

Si vous voulez éviter accidentelle supprime alors vous pourriez avoir une table factice qui déclare une clé étrangère dans votre table avec ON DELETE NO ACTION, et ajouter une ligne dans avec la clé étrangère correspondant à votre « précieux » ligne de clé primaire. De cette façon, si la ligne 'parent' est supprimée, le moteur refuse et déclenche une erreur.

Si vous souhaitez empêcher les suppressions intentionnelles, vous devez vous fier à la sécurité (refuser l'autorisation DELETE sur la table). Bien sûr, les utilisateurs privilégiés qui ont l'autorisation requise peuvent supprimer la ligne, il y a aucun moyen pour empêcher cela, et vous ne devriez pas essayer. Étant donné que SQL Server ne prend pas en charge la sécurité au niveau ligne, si vous devez refuser uniquement certaines lignes, vous devez revenir au dessin large et modifier votre disposition de table afin que toutes les lignes à refuser soient stockées dans une table, et les lignes autorisées à être supprimées sont stockées dans une table différente.

D'autres solutions (comme déclencheurs) sera en fin de compte une variation sur ces thèmes, ce que vous devez vraiment résoudre est la question de savoir si vous voulez éviter les suppressions accidentelles (résoluble) ou suppressions intentionnelles (impossibles à résoudre, est leur base de données, non le tiens).

+0

Je me demande si vous pouvez éviter la deuxième table en utilisant une clé étrangère auto-référence de cette manière. Réglez-le à l'Id dans les lignes que vous souhaitez protéger; défini sur NULL partout ailleurs. Hmmm ... –

+0

... eh bien, j'ai répondu à ma propre question: ça ne marche pas. Vous avez besoin de la deuxième table. Encore une bonne solution, cependant. –