Frage

Wir haben eine Benutzertabelle haben, hat jeder Benutzer eine eindeutige E-Mail und Benutzernamen ein. Wir versuchen, dies in unserem Code zu tun, aber wir wollen sicher sein, Benutzer nie eingefügt (oder aktualisiert) in der Datenbank mit dem gleichen Benutzername von E-Mail. Ich habe einen BEFORE INSERT Auslöser hinzugefügt, die das Einfügen von doppelten Benutzern verhindert.

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

Aber für den Update-Trigger Ich habe keine Ahnung, wie dies zu tun. Ich habe dieses Beispiel mit google gefunden: http: // www .devarticles.com / c / a / SQL-Server / Verwenden-Trigger-In-MS-SQL-Server / 2 / Aber ich weiß nicht, ob es gilt, wenn Sie mehrere Spalten auf einmal aktualisieren.

EDIT:

Ich habe versucht, eine eindeutige Einschränkung auf diesen Spalten hinzufügen, aber es funktioniert nicht:

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.
War es hilfreich?

Lösung

Sie können einen einzigartigen contraint auf dem Tisch hinzufügen, wird dies auf einen Fehler auslösen, wenn Sie versuchen, einzufügen oder zu aktualisieren, und erstellen Sie Duplikate

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

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

EDIT: Ok, ich habe gerade gelesen, um Ihre Kommentare zu einem anderen Beitrag und gesehen, dass Sie NVARCHAR (MAX) als Datentyp verwenden. Gibt es einen Grund, warum Sie mehr als 4000 Zeichen für eine E-Mail-Adresse oder Benutzername wollen? Dies ist, wo Ihr Problem liegt. Wenn Sie dies NVARCHAR reduzieren (250) oder so, dann können Sie einen eindeutigen Index verwenden.

Andere Tipps

Klingt wie eine Menge Arbeit, anstatt nur mit einem oder mehreren eindeutigen Indizes. Gibt es einen Grund, warum Sie nicht den Index Weg gegangen sind?

Warum verwendet nicht nur das UNIQUE-Attribut auf der Spalte in Ihrer Datenbank? diese Einstellung wird der SQL-Server, dass erzwingen und einen Fehler aus, wenn Sie versuchen, eine Betrogene einzufügen.

Sie sollten eine SQL UNIQUE Einschränkung für jede dieser Spalten für diese verwenden.

Sie können eine UNIQUE INDEX auf einem NVARCHAR erstellen, sobald es ein NVARCHAR(450) ist oder weniger.

Haben Sie wirklich brauchen eine UNIQUE Spalte so groß zu sein?

Im Allgemeinen würde ich Trigger vermeiden, wo immer möglich, da sie das Verhalten sehr schwer machen können, zu verstehen, wenn Sie wissen, dass der Auslöser vorhanden ist. Wie andere commentatators gesagt hat, eine eindeutige Einschränkung ist der Weg zu gehen (wenn Sie Ihre Spaltendefinitionen geändert haben, es zu ermöglichen).

Wenn Sie jemals feststellen, dass Sie einen Trigger zu verwenden, kann es ein Zeichen dafür sein, dass Ihr Design ist fehlerhaft. Ernsthaft darüber nachdenken, warum Sie sie brauchen und ob er ausführt, Logik, die an anderer Stelle gehört.

Beachten Sie, dass, wenn Sie die UNIQUE-Einschränkung / index Lösung mit SQL Server verwenden, nur eine Null-Wert wird in der Spalte zulässig. So zum Beispiel, wenn Sie die E-Mail-Adresse sein, optional wollten, wäre es nicht funktioniert, weil nur ein Benutzer eine Null-E-Mail-Adresse hat. In diesem Fall würden Sie einen anderen Ansatz wie ein Auslöser oder einen gefilterten Index zurückgreifen müssen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top