Question

Nous avons une table utilisateur, chaque utilisateur dispose d'un e-mail unique et nom d'utilisateur. Nous essayons de le faire dans notre code, mais nous voulons être sûr que les utilisateurs ne sont jamais insérés (ou mis à jour) dans la base de données avec le même nom d'utilisateur du courrier électronique. J'ai ajouté un déclencheur BEFORE INSERT qui empêche l'insertion d'utilisateurs en double.

CREATE TRIGGER [dbo].[BeforeUpdateUser]
   ON  [dbo].[Users]
   INSTEAD OF INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE @Email nvarchar(MAX)
    DECLARE @UserName nvarchar(MAX)
    DECLARE @UserId int
    DECLARE @DoInsert bit

    SET @DoInsert = 1

    SELECT @Email = Email, @UserName = UserName FROM INSERTED

    SELECT @UserId = UserId FROM Users WHERE Email = @Email

    IF (@UserId IS NOT NULL)
        BEGIN
            SET @DoInsert = 0
        END

    SELECT @UserId = UserId FROM Users WHERE UserName = @UserName

    IF (@UserId IS NOT NULL)
        BEGIN
            SET @DoInsert = 0
        END

    IF (@DoInsert = 1)
        BEGIN
            INSERT INTO Users
            SELECT 
                           FirstName, 
                           LastName, 
                           Email, 
                           Password, 
                           UserName, 
                           LanguageId,
                           Data, 
                           IsDeleted 
                       FROM INSERTED
        END
    ELSE
        BEGIN
            DECLARE @ErrorMessage nvarchar(MAX)
            SET @ErrorMessage = 
                         'The username and emailadress of a user must be unique!'
            RAISERROR 50001 @ErrorMessage
        END 
END

Mais pour le déclencheur de mise à jour je ne sais pas comment faire. J'ai trouvé cet exemple avec Google: http: // www .devarticles.com / c / a / SQL-serveur / Utilisation-triggers-In-MS-SQL-serveur / 2 / Mais je ne sais pas si elle applique lorsque vous mettez à jour plusieurs colonnes à la fois.

EDIT:

J'ai essayé d'ajouter une contrainte unique sur ces colonnes, mais il ne fonctionne pas:

Msg 1919, Level 16, State 1, Line 1
Column 'Email' in table 'Users' is of a type 
that is invalid for use as a key column in an index.
Était-ce utile?

La solution

Vous pouvez ajouter un unique sur le contraint table, cela soulèvera une erreur si vous essayez d'insérer ou de mettre à jour et créer des doublons

ALTER TABLE [Users] ADD  CONSTRAINT [IX_UniqueUserEmail] UNIQUE NONCLUSTERED 
(
    [Email] ASC
)

ALTER TABLE [Users] ADD  CONSTRAINT [IX_UniqueUserName] UNIQUE NONCLUSTERED 
(
    [UserName] ASC
)

EDIT: Ok, je viens de lire vos commentaires à un autre poste et vu que vous utilisez NVARCHAR (MAX) comme type de données. Y at-il une raison pour laquelle vous voudrez peut-être plus de 4000 caractères pour une adresse e-mail ou nom d'utilisateur? C'est là votre problème. Si vous réduisez cela NVARCHAR (250) ou à peu près, vous pouvez utiliser un index unique.

Autres conseils

Sons comme beaucoup de travail au lieu d'utiliser un ou plusieurs index uniques. Y at-il une raison que vous n'êtes pas allé la route de l'indice?

Pourquoi ne pas simplement utiliser l'attribut UNIQUE sur la colonne dans votre base de données? Réglage qui fera le serveur SQL et appliquer que jeter une erreur si vous essayez d'insérer une dupe.

Vous devez utiliser une contrainte SQL UNIQUE sur chacune de ces colonnes pour cela.

Vous pouvez créer un UNIQUE INDEX sur un NVARCHAR dès qu'il est un NVARCHAR(450) ou moins.

Avez-vous vraiment besoin d'une colonne de UNIQUE être si grand?

En général, je voudrais éviter Déclencheurs la mesure du possible, car ils peuvent rendre le comportement très difficile à comprendre, sauf si vous savez que le déclencheur existe. Comme d'autres commentatators ont dit, une contrainte unique est le chemin à parcourir (une fois que vous avez modifié vos définitions de colonne pour permettre).

Si jamais vous vous trouvez avoir besoin d'utiliser un déclencheur, il peut être un signe que votre conception est erronée. Réfléchissez bien à pourquoi vous en avez besoin et si elle exécute une logique qui appartient ailleurs.

Sachez que si vous utilisez la contrainte UNIQUE / solution d'index avec SQL Server, une seule valeur NULL est autorisée dans cette colonne. Ainsi, par exemple, si vous voulez l'adresse e-mail soit facultative, cela ne fonctionnerait pas, car seul un utilisateur pourrait avoir une adresse e-mail null. Dans ce cas, vous devez recourir à une autre approche comme un déclencheur ou un index filtré.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top