0
votes

Déclencheur qui exclut certains mots

J'ai une question liée aux déclencheurs de base de données dans T-SQL.

Je veux créer un déclencheur qui permet uniquement des mots spécifiques (disponibles, non disponibles) à une colonne Avalability .

Comment cela pourrait être fait?

Je comprends ce que la gâchette est, mais perdue dans la séquence de commandes - que devraient venir après quoi.


5 commentaires

Dupliqué possible de SQL Server - avant insérer le déclencheur


Vous ne savez pas que vous avez vraiment besoin d'une gâchette, pourquoi ne pas créer une contrainte cocher sur la colonne concernée?


Vous avez besoin d'un avant d'insérer déclencheur. Il y a beaucoup d'exemples via Google. Ou ce que @gmb suggère.


Cela sonne définitivement comme si vous décrivez Vérifier la contrainte pas un déclencheur .


Un déclencheur est absolument le mauvais outil de ce travail. Utilisez une contrainte de chèque.


4 Réponses :


5
votes

Je ne sais pas qu'un déclencheur est vraiment nécessaire ici. Une autre solution serait de créer une contrainte code> cocher code> sur la colonne concernée, comme: xxx pré>

Démo sur DB Fiddle Strong>: P>

CREATE TABLE TableName (availability VARCHAR(20) );

ALTER TABLE TableName
ADD CONSTRAINT availability_check CHECK (availability IN ('available', 'not available'));

INSERT INTO TableName(availability) VALUES('foo');

-- Error
Msg 547 Level 16 State 0 Line 1
The INSERT statement conflicted with the CHECK constraint "availability_check". The conflict occurred in database "fiddle_325b8b256056466caf52aa4bb7467fd7", table "dbo.TableName", column 'availability'.
Msg 3621 Level 0 State 0 Line 1
The statement has been terminated.


0 commentaires

3
votes

Il y a deux approches du problème.

  1. Go pour: Vérifier l'approche basée sur les contraintes forte>: vous pouvez y parvenir simplement en utilisant la contrainte de vérification. Il rend le travail plus simple, car @gmbe a déjà mentionné dans sa réponse. li> ol> xxx pré>
    1. ne pas aller pour: Approche basée sur la gâchette forte>: Si vous souhaitez créer un déclencheur, vous pouvez créer au lieu de déclencher comme indiqué ci-dessous. De plus, vous devez également créer Similaire au lieu de la mise à jour de la gâchette pour prendre en charge les scénarios de mise à jour. Mais c'est une approche détente. Voir la quantité de code requise, la maintenance correspondante. LI> OL>
      CREATE TRIGGER [dbo].[tr_availability_update]
              ON [dbo].[Table1]
              INSTEAD OF UPDATE
          AS
          BEGIN
          BEGIN TRY
          BEGIN TRANSACTION
          SET NOCOUNT ON;
      
          IF (inserted.Availability IN ('available', 'not available'))
          BEGIN 
          UPDATE Table1
          SET Availability = inserted.Availability
          WHERE Table1.Id = inserted.Id;
          END
      
          COMMIT;
          END TRY
          BEGIN CATCH
      
          IF @@TRANCOUNT > 0
               ROLLBACK
      
          RETURN;
          END CATCH
      


5 commentaires

Il est possible de faire avec un déclencheur, mais: 1. Vous devrez écrire du code similaire pour le moment où un utilisateur tente de mettre à jour la colonne. 2. Vous devrez fournir des instructions d'insertion / mise à jour pour toutes les colonnes de la table dans vos déclencheurs. Ce n'est pas un problème terrible, mais c'est quelque chose qui facilite la maintenance de la base de données plus difficile.


@Zoharpeled, d'accord avec vous. Je viens de fournir le code afin qu'il puisse comprendre la quantité de travail impliquée. J'ai également mentionné que, à nouveau, il doit écrire au lieu de la mise à jour de la gâchette. Je recommande moi-même que vous ne recommandez que le contrainte.


@Zoharpeled, j'ai mis à jour ma réponse pour clarifier la quantité d'effort nécessaire


si (inséré.Vailabilité dans ("disponible", "non disponible") a des parenthèses déséquilibrées et ce n'est pas clair comment il vérifie toutes les lignes dans insérées . Mise à jour de la table1 (disponibilité) Définir la disponibilité = inséré.Vailability est également un peu mystérieux quant à la manière dont il sélectionne les données à partir de insérées , mais au moins il met à jour toutes les lignes dans le tableau car il n'y a pas de clause.


@Habo, merci d'avoir attrapé le problème. corrigé-les. Je voulais juste mentionner la complexité de l'effort. OP n'a pas fourni de schéma de table et tout. Vient de mentionner l'effort.



5
votes

Vous pouvez alter code> votre table et ajouter une contrainte de coche code> directement sous xxx pré>

Notez que cela lancera une erreur s'il y a Certaines données déjà insérées dans la table et ne correspondent pas et contrairement à la contrainte Vérifiez code>. p>

Si vous ne code> Créez-vous encore votre table, Ensuite, vous pouvez utiliser P>

CREATE TABLE YourTableName(
  Availability VARCHAR(20) NOT NULL
    CONSTRAINT CHK_Avalability CHECK(Availability IN('Available', 'Not Available')) 
);


0 commentaires

1
votes

Une contrainte de contrôle est la façon dont j'irais. Une autre approche consiste à utiliser des contraintes référentielles, alias les clés primaire et étrangère. Si "disponible" et "non disponible" sont utilisés dans plusieurs endroits, cela sera meilleur qu'une contrainte de contrôle, car vous pouvez appliquer les mêmes règles sur plusieurs tables. De cette façon, vous pouvez appliquer la cohérence et éviter d'avoir des tables avec les autres valeurs telles que "disponibles" et "indisponible".

-- Lookup table for all possible "Availability" values
CREATE TABLE dbo.LU_Availability
(
  AvailabilityPK VARCHAR(14) NOT NULL,
  CONSTRAINT pk_LU_Availability PRIMARY KEY CLUSTERED(AvailabilityPK)
);
INSERT dbo.LU_Availability (AvailabilityPK) VALUES ('Available'),('Not Available');

-- Table with the allowable values enforced via foriegn key constraint
CREATE TABLE dbo.YourTable
(
  someId         INT IDENTITY,
  someValue      CHAR(10),
  [Availability] VARCHAR(14) NOT NULL,
  CONSTRAINT fk_AvailabilityTxt FOREIGN KEY([Availability]) 
    REFERENCES dbo.LU_Availability(AvailabilityPK)
);

INSERT dbo.YourTable ([Availability]) VALUES ('Available');     -- Succeeds
INSERT dbo.YourTable ([Availability]) VALUES ('NOT Available'); -- Succeeds
INSERT dbo.YourTable ([Availability]) VALUES ('Perhaps');       -- Fails


0 commentaires