إدخال البيانات في جدول SQL باستخدام المفتاح الأساسي.بالنسبة للمغفلين - هل تريد السماح بإدراج خطأ أو تحديد أولاً؟

StackOverflow https://stackoverflow.com/questions/411575

  •  03-07-2019
  •  | 
  •  

سؤال

إعطاء جدول مثل:

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، وإذا كان السجل موجود مسبقا، وتقديم للمستخدم فرصة لعرض و / أو تحريره.

وعلى سبيل المثال، إذا كان المستخدم يضيف رقما قياسيا جديدا العملاء، لأنها قد تحتاج إلى مراجعة المعلومات التي تم عرضها لهذا العميل. قد يكون لديهم معلومات إضافية إضافة إلى سجل، مثل رقم هاتف.

في هذا النوع من السيناريو، رافضا إضافة سجل أقل فائدة من توفر القدرة لعرض المكررة الحالية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top