2012-06-20 16 views
9

के बीच एक SQL XOR प्रतिबंध जोड़ें, मैं एक तालिका में दो शून्य फीके के बीच एक बाधा परिभाषित करना चाहता हूं, जहां कोई शून्य है, तो दूसरे को एक मूल्य की आवश्यकता है, लेकिन दोनों शून्य नहीं हो सकते हैं और दोनों नहीं कर सकते मूल्य है तर्क यह है कि व्युत्पन्न तालिका को इसके प्रकार निर्धारित करने के लिए एफके तालिकाओं में से किसी एक से डेटा प्राप्त होता है। इसके अलावा, मजेदार बोनस अंक के लिए, क्या यह एक बुरा विचार है?दो शून्य के FK के

+1

[आप यहां दिखाए गए सुपर प्रकार/उप प्रकार के पैटर्न पर भी विचार कर सकते हैं] (http://stackoverflow.com/q/7771869/73226) –

उत्तर

11

एक तरह से इसे प्राप्त करने के लिए बस को लिखने के लिए क्या "विशेष या" वास्तव में इसका मतलब है:

CHECK (
    (FK1 IS NOT NULL AND FK2 IS NULL) 
    OR (FK1 IS NULL AND FK2 IS NOT NULL) 
) 

हालांकि, अगर आप कई FKS है, उपरोक्त विधि जल्दी से, बोझल बन सकता है जो मामले में आप कर सकते हैं कुछ इस तरह करते हैं:

CHECK (
    1 = (
     (CASE WHEN FK1 IS NULL THEN 0 ELSE 1 END) 
     + (CASE WHEN FK2 IS NULL THEN 0 ELSE 1 END) 
     + (CASE WHEN FK3 IS NULL THEN 0 ELSE 1 END) 
     + (CASE WHEN FK4 IS NULL THEN 0 ELSE 1 END) 
     ... 
    ) 
) 

BTW, वहाँ उस पैटर्न के लिए वैध का उपयोग करता है, उदाहरण के this one के लिए (एमएस एसक्यूएल सर्वर के लिए लागू नहीं यद्यपि आस्थगित की कमी की कमी के कारण) कर रहे हैं। चाहे यह आपके विशेष मामले में वैध है, मैं अब तक प्रदान की गई जानकारी के आधार पर निर्णय नहीं ले सकता हूं।

+3

सरल: 'जांच करें (एफके 1 आईएस नल! = एफके 2 आईएसएलएल है) ' –

+0

@ स्टीफनजे। फुहरी दुख की बात है, एमएस एसक्यूएल सर्वर बुलीयन प्रकार को प्रथम श्रेणी के नागरिक के रूप में नहीं मानता है, ताकि वाक्यविन्यास स्वीकार नहीं किया जाएगा। –

+0

लेकिन यह PostgreSQL में काम करता है, जो मुझे इसके लिए जरूरी है। लघु अभिव्यक्ति के लिए धन्यवाद, @ स्टीफनजे। फुहरी। बेशक, एक्सओआर होना बेहतर होगा। यह देखते हुए कि सिस्टम में कितनी चीजें ढीली हुई हैं जो एक अजीब चूक लगती है। – mARK

1

आप check constraint उपयोग कर सकते हैं:

create table #t (
    a int, 
    b int); 

alter table #t add constraint c1 
check (coalesce(a, b) is not null and a*b is null); 

insert into #t values (1,null); 

insert into #t values (null ,null); 

रनिंग:

The INSERT statement conflicted with the CHECK constraint "c1". 
+1

'coalesce (a, b) 'गैर-नल वापस लौटाएगा ** दोनों ** 'ए' और' बी' गैर-नल हैं और जांच पास हो जाएगी, जो इसे नहीं करना चाहिए (ओपी स्पष्ट था कि दोनों के पास मूल्य नहीं हो सकते हैं)। दूसरे शब्दों में, '#t मानों (1, 1) में डालें' विफल होना चाहिए। –

+0

सुनिश्चित करें। धन्यवाद। मैं अपना जवाब ठीक कर दूंगा। – danihp

0

वैकल्पिक रास्ता एक प्रक्रिया में इस चेक बाधा परिभाषित करने के लिए है। व्युत्पन्न तालिका में एक रिकॉर्ड डालने से पहले, बाधा संतुष्ट होनी चाहिए। अन्य प्रविष्टि विफल रहता है या एक त्रुटि देता है।

संबंधित मुद्दे