2012-04-23 23 views
20


मुझे पता है कि एसक्यूएल में एक सशर्त नहीं शून्य बाधा उत्पन्न करना संभव है? दूसरे शब्दों में यह एक बाधा उत्पन्न करना संभव है कि कॉलम बी लंबे कॉलम के रूप में शून्य हो सकता है ए में शामिल है 'नया' कहें लेकिन यदि कॉलम ए की सामग्री किसी और चीज में बदल जाती है तो कॉलम बी को अब शून्य होने की अनुमति नहीं है?
और उस पर विस्तार करने के लिए, तो इसे बनाना संभव है ताकि स्तंभ बी को तब तक खाली या खाली होना चाहिए जब तक कॉलम ए 'नया' कहता है?
धन्यवाद सभी: डी
एसक्यूएल सशर्त नहीं शून्य प्रतिबंध

+0

Fwiw, मुझे नहीं लगता कि सबसे डेटाबेस डिजाइनरों यह एक सशर्त बाधा कहेंगे है। * मैं * शायद इसे केवल एक बाधा कहूंगा, लेकिन अगर मुझे इसे और अधिक योग्यता प्राप्त करनी पड़ी, तो मैं इसे बहु-कॉलम बाधा या बहु-स्तंभ जांच() बाधा कह सकता हूं। यह मानक एसक्यूएल है। –

+0

@Catcall: क्रिस डेट उद्धरण: "कभी-कभी ऐसी बाधाओं को अनौपचारिक रूप से, तुलनीय बाधाओं या एसक्यूएल में पंक्ति बाधाओं के रूप में संदर्भित किया जाता है-हालांकि यह बाद का शब्द एसक्यूएल में भी इसका मतलब है, अधिक विशेष रूप से, एक पंक्ति बाधा जो नहीं कर सकती कॉलम बाधा के रूप में तैयार किया जाना चाहिए ... ऐसे सभी उपयोग बहिष्कृत किए गए हैं, हालांकि, बाधाएं अद्यतनों को बाधित करती हैं और ... संबंधपरक दुनिया में टुपल या पंक्ति स्तर अद्यतन जैसी कोई चीज़ नहीं है। " – onedaywhen

+0

@onedaywhen: मेरे पास वर्तमान संस्करण नहीं है। 7 वें संस्करण में, जो मैं यहां देख रहा हूं (न्यूल के अलावा) वह एक रिवर बाधा (पी 253) कहता है।यह कई कॉलम को समायोजित करता है, और वह कहता है कि यह मनमाने ढंग से जटिल हो सकता है (अर्थात्, मुझे लगता है कि यह अन्य संबंधों, विचारों, समेकन और चंद्रमा के चरणों को संदर्भित कर सकता है)। –

उत्तर

23

यह कंसस्ट्रेंट चेक के लिए बिल्कुल ठीक है। बस इस कार्य करें:

आवश्यकता:

यह इस तरह की कोई समस्या एक स्तंभ बी अशक्त रूप में लंबे समय स्तंभ एक में शामिल किया जा सकता है बनाने के लिए संभव है का कहना है की सुविधा देता है 'नए' लेकिन अगर स्तंभ एक की सामग्री किसी और चीज में परिवर्तन तब कॉलम बी को शून्य होने की अनुमति नहीं है?

नोट वाक्यांश:

create table tbl 
(
    A varchar(10) not null, 
    B varchar(10), 

    constraint uk_tbl check 
    (
     A = 'NEW' -- B can be null or not null: no need to add AND here 
     OR (A <> 'NEW' AND B IS NOT NULL) 
    ) 
); 

आप इसे आगे सरल कर सकते हैं::

create table tbl 
(
    A varchar(10) not null, 
    B varchar(10), 

    constraint uk_tbl check 
    (
     A = 'NEW' 
     OR B IS NOT NULL 
    ) 
); 

आवश्यकता परस्पर असंगत स्तंभ बी अशक्त

समाधान हो सकता है आवश्यकता से अधिक करने के लिए:

और उस पर विस्तार करने के लिए, यह इतना है कि स्तंभ बी अशक्त है या जब तक खाली स्तंभ ए 'नई' का कहना है के रूप में करना चाहिए बनाने के लिए तो संभव है?

नोट वाक्यांश: स्तंभ बी चाहिए अशक्त हो

create table tbl 
(
    A varchar(10) not null, 
    B varchar(10), 

    constraint uk_tbl check 
    (
     (A = 'NEW' AND B IS NULL) 
     OR A <> 'NEW' 
    ) 
); 

इस के साथ सरल किया जा सकता है, सरल लेकिन हालांकि इसके बाद के संस्करण के रूप में के रूप में पढ़ने योग्य नहीं हो सकता है:

create table tbl 
(
    A varchar(10) not null, 
    B varchar(10), 

    constraint uk_tbl check 
    (
     A <> 'NEW' 
     OR B IS NULL 
    ) 
); 
+3

मेरा मानना ​​है कि एकमात्र आधुनिक एसक्यूएल डीबीएमएस यह * काम नहीं करेगा * MySQL है। MySQL जांच() बाधाओं को लागू नहीं करता है। (प्रश्न "एसक्यूएल" टैग किया गया है, इसलिए एक टिप्पणी प्रासंगिक लगती थी।) –

+0

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

+0

का उपयोग कर रहे आरडीबीएमएस पर अधिक विशिष्ट हो सकता है कि यह बाधा जांच पहले से ही पोस्टग्रेस्क्ल पर 1 दिन से एसक्यूएल सर्वर पर काम कर रही है। मैंने परीक्षण किया कि SQL सर्वर और Postgresql दोनों पर डीडीएल, दोनों इसे स्वीकार करते हैं –

0

प्रति onedaywhen, इस सवाल का जवाब आपराधिक गलत है, और एक abomination। आप चेक बाधा का उपयोग कर सकते हैं। http://msdn.microsoft.com/en-us/library/ms188258.aspx

सशर्त बाधाओं को बनाने का कोई तरीका नहीं है। हालांकि, आपको ट्रिगर का उपयोग करके नौकरी करने में सक्षम होना चाहिए। यही वह है जो वे हैं।

http://msdn.microsoft.com/en-us/library/ms189799.aspx

CREATE TRIGGER MyTable.ConditionalNullConstraint ON MyTable.ColumnB 
AFTER INSERT 
AS 
IF EXISTS (SELECT * 
    FROM inserted 
    WHERE A <> 'NEW' AND B IS NULL 
    ) 
BEGIN 
    RAISERROR ('if A is ''NEW'' then B cannot be NULL', 16, 1); 
    ROLLBACK TRANSACTION; 
END; 
GO 

ध्यान दें कि क्वेरी में आप संदर्भ के लिए डाला जो एक विशेष उद्देश्य यह है कि एक मेज की तरह बर्ताव करता है चाहता हूँ, और कहा कि ट्रिगर वजह से आप पंक्ति (यों) का संदर्भ देता है ।

बेशक, इस उदाहरण में आपको को अद्यतन करने के बाद भी बाधा को लागू करने की आवश्यकता होगी, लेकिन यह सामान्य विचार है।

+0

"सशर्त बाधाओं का कोई तरीका नहीं है" हू? इसे एक ट्यूपल बाधा ('चेक') द्वारा नियंत्रित किया जा सकता है और इस मामले में एक ट्रिगर पर प्राथमिकता दी जानी चाहिए। – onedaywhen

+0

@onedaywhen वाह, मैं बहुत सही खड़ा हूँ, धन्यवाद। जांच बाधा: http://msdn.microsoft.com/en-us/library/ms188258.aspx – McGarnagle

1

संपादित करें: जैसा कि अन्य उत्तरों में उल्लिखित है, एक जांच सबसे अच्छी विधि है, न कि ट्रिगर जिसे मैंने मूल रूप से सुझाया था। मूल पाठ इस प्रकार है:


dbaseman पता चलता है, चलाता जाना (नहीं तो) तरीका है। इस तरह कुछ प्रयास करें (अवांछित):

CREATE OR REPLACE TRIGGER test 
    BEFORE UPDATE ON table1 
FOR EACH ROW 
WHEN (new.A = 'NEW' and new.B IS NOT NULL) 
    RAISE_APPLICATION_ERROR (
    num=> -20001, 
    msg=> 'B must be NULL for new rows (A = NEW)' 
); 
+0

स्पष्टता के लिए, यह समाधान ओरेकल के लिए है। dbaseman जो मैं मानता हूं उसके लिए एक समाधान प्रदान करता है MSSQL :) – dwurf

+0

ओरेकल ट्यूपल बाधाओं का समर्थन करता है ('चेक '): घोषणात्मक बाधाओं को प्रक्रियात्मक कोड (ट्रिगर्स समेत) से ऊपर चुना जाना चाहिए। – onedaywhen

1

मुझे लगता है कि आपकी पहली निर्दिष्ट आवश्यकता है:

IF (B IS NULL) THEN (A = 'NEW') 

निहितार्थ पुनर्लेखन नियम लागू करें:

IF (X) THEN (Y) <=> (NOT (X) OR (Y)) 

आपके मामले में;

(NOT (B IS NULL) OR (A = 'NEW')) 

माइनर पुनर्लेखन SQL सिंटैक्स का लाभ लेने के:

(B IS NOT NULL OR A = 'NEW') 

आपकी दूसरी कहा ("विस्तार") की आवश्यकता:

:

IF (A = 'NEW') THEN (B IS NULL) 

पुनर्लेखन नियम लागू करें

(NOT (A = 'NEW') OR (B IS NULL)) 

माइनर रीराइट:

(A <> 'NEW' OR B IS NULL) 
संबंधित मुद्दे