2011-01-26 11 views
18

मेरे पास bit IsDefault कॉलम है। तालिका के भीतर डेटा की केवल एक पंक्ति में यह बिट कॉलम 1 पर सेट हो सकता है, अन्य सभी 0 होना चाहिए।एसक्यूएल सर्वर बिट कॉलम बाधा, 1 पंक्ति = 1, अन्य सभी 0

मैं इसे कैसे लागू कर सकता हूं?

+6

क्या आपने एक वैकल्पिक वास्तुकला माना है? कहें, कहीं और संदर्भ है जो "डिफ़ॉल्ट" पंक्ति को इंगित करता है। –

+1

एसक्यूएल सर्वर का कौन सा संस्करण कृपया? – gbn

+0

क्या एक अच्छा सवाल है! मैं केवल प्रशंसा के अपने अन्य + 99 अंक व्यक्त करने के लिए इसे लिख रहा हूं। –

उत्तर

30

सभी संस्करणों:

  • उत्प्रेरक
  • इंडेक्स्ड दृश्य
  • संग्रहीत proc (लिखने पर जैसे परीक्षण)

एसक्यूएल सर्वर 2008: a filtered index

CREATE UNIQUE INDEX IX_foo ON bar (MyBitCol) WHERE MyBitCol = 1 
+0

अच्छा, यह निश्चित रूप से उन्हें डिफ़ॉल्ट रूप से एकाधिक रिकॉर्ड सहेजने से रोक देगा। – NotMe

+1

फ़िल्टर किए गए इंडेक्स को एएनएसआई पैडिंग चालू करने की आवश्यकता है। तो फ़िल्टर किए गए इंडेक्स बनाने से पहले 'सेट एएनएसआई पैडिंग ऑन 'निष्पादित करें। – naXa

1

आप कर सकते थे इसके बजाए आवेदन करें ट्रिगर डालें और मान की जाँच के रूप में यह में आ रहा है।

Create Trigger TRG_MyTrigger 
on MyTable 
Instead of Insert 
as 
Begin 

    --Check to see if the row is marked as active.... 
    If Exists(Select * from inserted where IsDefault= 1) 
    Begin 
    Update Table Set IsDefault=0 where ID= (select ID from inserted); 

    insert into Table(Columns) 
    select Columns from inserted 
    End 

End 

वैकल्पिक रूप से आप स्तंभ पर एक अद्वितीय बाधा लागू हो सकते हैं।

16

अपने पी मान लिया जाये कि एक एकल, संख्यात्मक कॉलम है, आप अपनी तालिका में एक गणना स्तंभ जोड़ सकते हैं:

ALTER TABLE YourTable 
    ADD IsDefaultCheck AS CASE IsDefault 
    WHEN 1 THEN -1 
    WHEN 0 THEN YourPK 
    END 

फिर गणना स्तंभ पर एक अद्वितीय सूचकांक पैदा करते हैं।

CREATE UNIQUE INDEX IX_DefaultCheck ON YourTable(IsDefaultCheck) 
+0

+1 ने कभी इस बारे में सोचा नहीं। एक फ़िल्टर सूचकांक – gbn

+0

+ 1 अच्छा समाधान के बिना एक डीआरआई समाधान। –

+0

यह मेरी राय में सबसे अच्छा समाधान है, क्योंकि इसमें कोई ट्रिगर नहीं है। वास्तव में, इस समाधान में प्रदान की गई सब कुछ शायद मूल तालिका परिभाषा में इनलाइन लागू की जा सकती है। – Tripartio

2

मुझे लगता है कि ट्रिगर सबसे अच्छा विचार है जब आप सम्मिलित/एक नया अद्यतन 0 करने के लिए पुराने डिफ़ॉल्ट रिकॉर्ड को बदलना चाहते हैं और क्या आप वाकई एक रिकॉर्ड बनाना चाहते हैं तो हमेशा उस महत्व है (यानी अगर आप उस मान के साथ रिकॉर्ड हटाते हैं जिसे आप इसे एक अलग रिकॉर्ड में असाइन करेंगे)। आपको ऐसा करने के नियमों पर फैसला करना होगा। ये ट्रिगर मुश्किल हो सकते हैं क्योंकि आपको सम्मिलित और हटाए गए तालिकाओं में एकाधिक रिकॉर्ड के लिए खाते हैं। तो यदि बैच में 3 रिकॉर्ड डिफ़ॉल्ट रिकॉर्ड बनने के लिए अपडेट करने का प्रयास करते हैं, तो कौन सा जीतता है?

यदि आप यह सुनिश्चित करना चाहते हैं कि कोई डिफ़ॉल्ट रिकॉर्ड कभी नहीं बदलता है जब कोई और इसे बदलने का प्रयास करता है, तो फ़िल्टर किया गया इंडेक्स एक अच्छा विचार है।

1

नीचे प्रश्न के स्वीकार किए जाते हैं जवाब दोनों रोचक और प्रासंगिक है: "। लेकिन गंभीर रिलेशनल लोगों आप इस जानकारी को सिर्फ एक और तालिका में होना चाहिए बता देंगे"

Constraint for only one record marked as default

एक अलग 1 पंक्ति तालिका है जो आपको बताती है कि कौन सा रिकॉर्ड 'डिफ़ॉल्ट' है। Anon ने अपनी टिप्पणी में इस पर छुआ।

मुझे लगता है कि यह सबसे अच्छा तरीका है - सरल, स्वच्छ & एक 'चतुर' गूढ़ समाधान त्रुटियों या बाद में गलतफहमी होने का खतरा आवश्यकता नहीं है। आप IsDefualt कॉलम भी छोड़ सकते हैं।

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