it-swarm.asia

التحقق من القيد واحد فقط من الأعمدة الثلاثة غير فارغ

لدي جدول (SQL Server) يحتوي على 3 أنواع من النتائج: FLOAT أو NVARCHAR (30) أو DATETIME (3 أعمدة منفصلة). أريد التأكد من أنه بالنسبة لأي صف معين ، ينتج عن عمود واحد فقط والأعمدة الأخرى فارغة. ما هو أبسط قيد تحقق لتحقيق ذلك؟

يحاول سياق هذا التعديل التحديثي للقدرة على التقاط نتائج غير رقمية في نظام موجود. كانت إضافة عمودين جديدين إلى الجدول مع تقييد لمنع أكثر من نتيجة واحدة لكل صف هي النهج الأكثر اقتصادا ، وليس بالضرورة الصحيح.

تحديث: عذرا ، نوع البيانات snafu. للأسف لم أكن أنوي أنواع النتائج المشار إليها ليتم تفسيرها على أنها أنواع بيانات SQL Server ، فقط مصطلحات عامة ، تم إصلاحها الآن.

65
David Clarke

يجب أن تفعل الخدعة التالية:

CREATE TABLE MyTable (col1 FLOAT NULL, col2 NVARCHAR(30) NULL, col3 DATETIME NULL);
GO

ALTER TABLE MyTable
ADD CONSTRAINT CheckOnlyOneColumnIsNull
CHECK 
(
    ( CASE WHEN col1 IS NULL THEN 0 ELSE 1 END
    + CASE WHEN col2 IS NULL THEN 0 ELSE 1 END
    + CASE WHEN col3 IS NULL THEN 0 ELSE 1 END
    ) = 1
)
GO
78
Mark Storey-Smith

ربما ستحتاج إلى إجراء ثلاثة اختبارات داخل القيد ، اختبار واحد لكل زوج تريد أن يكون فارغًا وآخر للعمود الذي يجب ألا يكون خاليًا:

ALTER TABLE table
ADD CONSTRAINT CK_one_is_null
CHECK (
     (col1 IS NOT NULL AND col2 IS NULL AND col3 IS NULL)
  OR (col2 IS NOT NULL AND col1 IS NULL AND col3 IS NULL) 
  OR (col3 IS NOT NULL AND col1 IS NULL AND col2 IS NULL)
);
24
mrdenny

فيما يلي حل PostgreSQL باستخدام وظائف الصفيف المضمنة :

ALTER TABLE your_table
ADD chk_only_one_is_not_null CHECK (array_length(array_remove(ARRAY[col1::text, col2::text, col3::text], NULL), 1) = 1);
5
CrEOF

FOR POSTGRESQL

CHECK( (col_1 IS NOT NULL)::integer + (col_2 IS NOT NULL)::integer + ... = 1 )

نقوم بتحويل العمود إلى منطقي مع IS NOT NULL ( صحيح أو false ) ، ثم يلقي في :: عدد صحيح ( 0 أو 1 ) يمكننا بعد ذلك استخدام العمليات الحسابية

= 1  //must one row is not null  
<= 1 //only one row can be not null
1
Mendes