Die toevoeging van'n beperking om te verhoed duplikate in SQL Update Sneller
-
23-08-2019 - |
Vra
Ons het'n gebruiker tafel, elke gebruiker het'n unieke e-pos en gebruikersnaam.Ons probeer om dit te doen binne ons kode, maar ons wil seker wees dat die gebruikers is nooit ingevoeg (of opgedateer) in die databasis met die dieselfde gebruikersnaam van e-pos.Ek het bygevoeg'n BEFORE INSERT
Die sneller wat verhoed dat die invoeging van duplikaat gebruikers.
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
Maar vir die Werk sneller ek het geen Idee hoe om dit te doen.Ek het gevind dat hierdie voorbeeld met google:http://www.devarticles.com/c/a/SQL-Server/Using-Triggers-In-MS-SQL-Server/2/ Maar ek weet nie of dit van toepassing is wanneer jy werk verskeie kolomme op een slag.
EDIT:
Ek het probeer om by te voeg'n unieke beperking op hierdie kolomme maar dit werk nie:
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.
Oplossing
Jy kan 'n unieke contraint voeg op die tafel, sal dit 'n fout maak as jy probeer en voeg of te werk en duplikate skep
ALTER TABLE [Users] ADD CONSTRAINT [IX_UniqueUserEmail] UNIQUE NONCLUSTERED
(
[Email] ASC
)
ALTER TABLE [Users] ADD CONSTRAINT [IX_UniqueUserName] UNIQUE NONCLUSTERED
(
[UserName] ASC
)
EDIT: Ok, ek het net lees jou kommentaar na 'n ander pos en gesien dat jy met behulp van NVARCHAR (MAX) as jou data tipe. Is daar 'n rede waarom jy dalk wil meer as 4000 karakters vir 'n e-pos adres of gebruikersnaam? Dit is waar jou probleem lê. As jy hierdie na NVARCHAR (250) of daar omtrent verminder dan kan jy 'n unieke indeks te gebruik.
Ander wenke
Dit klink na 'n baie werk in plaas van net die gebruik van een of meer unieke indekse. Is daar 'n rede waarom jy nie die indeks roete gegaan?
Waarom nie net gebruik die unieke kenmerk van die kolom in jou databasis? Opstel wat sal maak dat die SQL-bediener af te dwing wat en gooi 'n fout as jy probeer om 'n bedrieg voeg.
Jy moet 'n SQL UNIQUE
beperking op elk van hierdie kolomme te gebruik vir daardie.
Jy kan 'n UNIQUE INDEX
skep op 'n NVARCHAR
so gou as dit is 'n NVARCHAR(450)
of minder.
Wil jy regtig nodig het 'n UNIQUE
kolom so groot te wees?
In die algemeen, ek sou vermy Snellers, waar moontlik, as hulle kan maak die gedrag baie moeilik om te verstaan tensy jy weet wat die sneller bestaan.As ander commentatators het gesê, 'n unieke beperking is die pad om te gaan (sodra jy gewysig jou kolom definisies om dit te laat).
As jy ooit vind jouself hoef te gebruik om'n sneller, dit kan'n teken dat jou ontwerp is gebrekkig.Dink hard oor die rede waarom jy dit nodig het en of dit is die uitvoering van die logika wat behoort elders.
Wees bewus daarvan dat as jy die unieke beperking / indeks oplossing met SQL Server te gebruik, net een nul waarde sal in daardie kolom toegelaat. So, byvoorbeeld, as jy wou die e-posadres te opsioneel wees, dit sal nie werk nie, want net een gebruiker 'n nul e-pos adres kan hê. In daardie geval, sal jy hê om plek na 'n ander benadering soos 'n sneller of 'n gefilterde indeks.