إضافة قيود لمنع التكرارات في تشغيل تحديث SQL
-
23-08-2019 - |
سؤال
لدينا جدول مستخدم، كل مستخدم لديه بريد إلكتروني فريد واسم المستخدم. نحاول القيام بذلك ضمن كودنا ولكن نريد أن نكون متأكدين من المستخدمين أبدا (أو تحديثهم) في قاعدة البيانات مع نفس اسم المستخدم عبر البريد الإلكتروني. لقد أضفت أ BEFORE INSERT
الزناد الذي يمنع إدراج المستخدمين المكررين.
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
ولكن لتحديث التحديث ليس لدي أي فكرة عن كيفية القيام بذلك. لقد وجدت هذا المثال مع Google:http://www.devarticles.com/c/a/sql-server/using-triggers-in-ms-sql-server/2/لكنني لا أعرف إذا كان ينطبق عند تحديث أعمدة متعددة في وقت واحد.
تعديل:
لقد حاولت إضافة قيود فريدة على هذه الأعمدة، لكنها لا تعمل:
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.
المحلول
يمكنك إضافة أعراض فريدة من نوعها على الجدول، وسوف يثير هذا خطأ إذا حاولت إدخال أو تحديث وإنشاء التكرارات
ALTER TABLE [Users] ADD CONSTRAINT [IX_UniqueUserEmail] UNIQUE NONCLUSTERED
(
[Email] ASC
)
ALTER TABLE [Users] ADD CONSTRAINT [IX_UniqueUserName] UNIQUE NONCLUSTERED
(
[UserName] ASC
)
تحرير: حسنا، لقد قرأت تعليقاتك فقط إلى منشور آخر ورأيت أنك تستخدم NVARCHAR (MAX) كوعي بياناتك. هل هناك سبب لماذا قد ترغب في أكثر من 4000 حرفا لعنوان بريد إلكتروني أو اسم مستخدم؟ هذا هو المكان الذي تكمن مشكلتك. إذا قمت بتقليل هذا إلى NVARCHAR (250) أو ما بعد ذلك، يمكنك استخدام فهرس فريد.
نصائح أخرى
يبدو وكأنه الكثير من العمل بدلا من مجرد استخدام فهارس واحدة أو أكثر فريدة. هل هناك سبب لم تخطئ مسار الفهرس؟
لماذا لا تستخدم السمة الفريدة فقط في العمود في قاعدة البيانات الخاصة بك؟ الإعداد الذي سيجعل خادم SQL يفرض ذلك ورمي خطأ إذا حاولت إدراج Dupe.
يجب عليك استخدام SQL UNIQUE
قيد على كل من هذه الأعمدة لذلك.
يمكنك إنشاء UNIQUE INDEX
على NVARCHAR
بمجرد أن يكون NVARCHAR(450)
او اقل.
هل تحتاج حقا UNIQUE
العمود ليكون كبير جدا؟
بشكل عام، أود تجنب المشغلات حيثما كان ذلك ممكنا لأنها يمكن أن تجعل السلوك يصعب فهمها إلا إذا كنت تعرف أن الزناد موجود. كما قال المعلقون الآخرون، فإن القيد الفريد هو الطريق للذهاب (بمجرد تعديل تعريفات الأعمدة الخاصة بك للسماح بذلك).
إذا وجدت نفسك تحتاج إلى استخدام الزناد، فقد تكون علامة على أن التصميم الخاص بك معيبة. فكر بجد حول سبب حاجة إليها وما إذا كان الأمر يتعلق بالمنطق الذي ينتمي إلى مكان آخر.
كن على دراية أنه إذا كنت تستخدم حل القيد / الفهرس الفريد مع SQL Server، فسيتم السماح بالقيمة الفاتورة فقط في هذا العمود. لذلك، على سبيل المثال، إذا كنت ترغب في أن يكون عنوان البريد الإلكتروني اختياريا، فلن يعمل ذلك، لأن مستخدم واحد فقط قد يكون له عنوان بريد إلكتروني فارغا. في هذه الحالة، يجب عليك اللجوء إلى نهج آخر مثل الزناد أو الفهرس المصفى.