إدخال البيانات في جدول SQL باستخدام المفتاح الأساسي.بالنسبة للمغفلين - هل تريد السماح بإدراج خطأ أو تحديد أولاً؟
سؤال
إعطاء جدول مثل:
CREATE TABLE dbo.MyTestData (testdata varchar(50) NOT NULL)
ALTER TABLE dbo.MyTestData WITH NOCHECK ADD CONSTRAINT [PK_MyTestData] PRIMARY KEY CLUSTERED (testdata)
وبالنظر إلى أننا نريد قائمة فريدة من "بيانات الاختبار" عندما ننتهي من جمع العناصر المراد إضافتها من قائمة البيانات الخارجية ذات التكرارات المعروفة...عند تنفيذ إجراء مُخزن للإدراج، هل يجب كتابة الإجراء لاختبار وجوده أم أنه يجب أن يسمح فقط بالخطأ؟ما هي الممارسة الأكثر شيوعا؟لقد قمت دائمًا بإجراء اختبار الوجود ولكني كنت أناقش هذا الأمر الليلة الماضية ...
CREATE PROCEDURE dbo.dmsInsertTestData @ptestdata VarChar(50)
AS
SET NOCOUNT ON
IF NOT EXISTS(SELECT testdata FROM dbo.MyTestData WHERE testdata=@ptestdata)
BEGIN
INSERT INTO dbo.MyTestData (testdata ) VALUES (@ptestdata)
END
RETURN 0
أو مجرد التقاط/تجاهل أخطاء انتهاك PK عند تنفيذ هذا؟
CREATE PROCEDURE dbo.dmsInsertTestData @ptestdata VarChar(50)
AS
SET NOCOUNT ON
INSERT INTO dbo.MyTestData (testdata ) VALUES (@ptestdata)
RETURN 0
المحلول
وأنا دائما تفعل ذلك في عبارة واحدة:
INSERT INTO dbo.MyTestData (testdata ) VALUES (@ptestdata)
WHERE NOT EXISTS(SELECT 1 FROM dbo.MyTestData WHERE testdata=@ptestdata)
نصائح أخرى
التحقق الخاص بك من الأخطاء (أي."IF NOT EXISTS ...") قد تعمل أو لا تعمل، نظرًا لوجود حالة سباق محتملة (إذا قامت معاملة أخرى بإدراج السجل بعد عبارة IF NOT EXISTS الخاصة بك ولكن قبل عبارة INSERT الخاصة بك).
لذلك، سواء قمت بالتحقق من قبل أم لا، يجب عليك ترميز عبارة INSERT الخاصة بك كما لو أنها قد تفشل.
سواء كنت تريد التحقق أيضًا (ليس، بدلاً من ذلك) الأمر متروك لك ويعود إلى واجهة المستخدم الخاصة بك.
وأعتقد أن معظم المبرمجين تشير تجنب الاستثناء. لست متأكدا من وجهة نظر الأداء في T-SQL، ولكن في. NET على سبيل المثال، وأعتقد استثناء القيت هو أكثر تكلفة من للو / بيان آخر إضافي.
وقلقي مع المثال الأول الذي قدم هو أنه لا إرجاع خطأ للمستخدم. يمكن ان تكون ثابتة للقيام بذلك، ولكن أنا لن تستخدم إلا إذا كان إرجاع خطأ.
إذا قلقكم بين possibilties اثنين هو الأداء على جداول كبيرة، وأنا أقترح عليك اختبار كل منهم، ومعرفة ما إذا كان واحد هو أسرع بكثير من غيرها. إذا إذا حدد أمر معقد للغاية وسوف تضاف تحتاج أن يحدث حتى الآن معظم الوقت، فمن الممكن أن مجرد السماح لها الفشل سيكون أسرع في معظم الوقت. إذا على صعيد آخر، وإمكانية مساهمة سيئة عالية وإذا كان غير معقدة نسبيا كما هو موضح هنا، ثم عملية أخرى قد تكون أفضل واحد. ولكن فقط اختبار حقيقي في بنية البيانات الخاصة بك الحقيقي والبيانات ومع الاستفسارات الخاصة بك الحقيقي يمكن أن أقول لكم الذي هو واحد من اجل اداء افضل لأنها قد تكون مختلفون في situaltions deiffernt.
وأعتقد ان ذلك يعتمد على طبيعة الإجراء المخزن. في الأساس، يجب معالجة الأخطاء إذا كان لديك أن تفعل شيئا معهم (أو لتغليف لهم لعملاء الداخلي) وتركهم نشر إذا لم يكن لديك أي علاقة معهم، ولا يمكن جعلها أكثر ودا لأغراض أخرى طبقات من التطبيق.
إذا تم تصميم الإجراء المخزن لادخال البيانات الخام، وأعتقد أنه ينبغي ترك تطبيق لمعالجة الأخطاء المحتملة. إذا تم تصميم الإجراء المخزن كطبقة من التجريد (ويفعل مهمة محددة <ط> بدلا من تشغيل محددة <ط> بيان )، وإما أن معالجة الخطأ وتفعل شيئا معها أو يمكن الإبلاغ عنه بطريقة رشيقة (على سبيل المثال، رموز الخطأ واضحة المعالم) إلى التطبيق، يجب أن تفعل ذلك. خلاف ذلك، ينبغي أن يكون ما يصل إلى التطبيق للتأكد من انها ليست إدخال البيانات المكررة، وليس قاعدة البيانات (قاعدة بيانات فرضت بالفعل هذا مع المفاتيح الأساسية).
في ترتيب لتكون سهلة الاستخدام، فإنه في كثير من الأحيان ممارسة جيدة لأداء SELECT، وإذا كان السجل موجود مسبقا، وتقديم للمستخدم فرصة لعرض و / أو تحريره.
وعلى سبيل المثال، إذا كان المستخدم يضيف رقما قياسيا جديدا العملاء، لأنها قد تحتاج إلى مراجعة المعلومات التي تم عرضها لهذا العميل. قد يكون لديهم معلومات إضافية إضافة إلى سجل، مثل رقم هاتف.
في هذا النوع من السيناريو، رافضا إضافة سجل أقل فائدة من توفر القدرة لعرض المكررة الحالية.