दो अशक्त स्तंभों में एक मान होना आवश्यक है


10

नो-स्पष्टीकरण प्रश्न:

वहाँ वैसे भी 2 अशक्त मूल्यों की एक विवशता है कि हमेशा मूल्य के लिए 1 की आवश्यकता होती है? उदाहरण के लिए दो तारीख स्तंभ दोनों शून्य हैं, लेकिन कम से कम 1 है जिसमें एक मान होना आवश्यक है

समस्या का विवरण:

मान लीजिए कि मेरे पास व्यय नामक तालिका है

और 2 तारीखें हैं:

prevision_expense_expiration_date दिनांक NULLABLE व्यय_पेमेंट_डेट DATE NULLABLE

उन 2 स्तंभों का तर्क निम्नलिखित है:

मैंने कुछ की खरीदारी की और मुझे पता है कि मुझे इसके लिए भुगतान करना होगा, कुछ तारीख, जैसे फोन बिल। मैं एक व्यय_पेमेंट_डेट के साथ व्यय के रूप में दर्ज करूंगा। यह तिथि वह तिथि है जिसे मुझे भुगतान करना चाहिए, लेकिन भुगतान की वास्तविक तिथि, चालान की समाप्ति तिथि की तरह नहीं।

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

मुझे पता है कि मेरे पास 2 समान रूप से टेबल हो सकते हैं जिन्हें प्रीविज़न_एक्सपेन्स और कन्फर्म_फंसेन्स कहा जाता है, लेकिन यह सही नहीं लगता है इसलिए मेरे पास एक ही टेबल, 2 तारीख, अशक्त है, लेकिन मैं विवश या कुछ करना चाहता हूं ताकि एक की हमेशा आवश्यकता हो।

एक और सकारात्मक रणनीति है:

payment_date पूरा नहीं है

तो, इस मामले में, यदि तारीख प्रीविजन है बूल वैल्यू 1 होगी, अन्यथा 0. कोई शून्य मान नहीं होगा, सब अच्छा है। सिवाय इसके कि मैं बीओटीएच मूल्यों को संग्रहीत करने का विकल्प चाहता हूं, जब पहले मेरे पास एक प्रीव्यू डेट है और उस खर्च के लिए THEN (दो दिन बाद कहते हैं) की पुष्टि की तारीख है, उस स्थिति में रणनीति 2 के साथ मेरे पास वह विकल्प नहीं होगा।

मैं डेटाबेस डिजाइन में सब कुछ गलत कर रहा हूँ? : डी

जवाबों:


10

जेडी श्मिट के जवाब का एक संस्करण, लेकिन एक अतिरिक्त स्तंभ की अजीबता के बिना:

CREATE TABLE foo (
  FieldA INT,
  FieldB INT
);

DELIMITER //
CREATE TRIGGER InsertFieldABNotNull BEFORE INSERT ON foo
FOR EACH ROW BEGIN
  IF (NEW.FieldA IS NULL AND NEW.FieldB IS NULL) THEN
    SIGNAL SQLSTATE '45000'
    SET MESSAGE_TEXT = '\'FieldA\' and \'FieldB\' cannot both be null';
  END IF;
END//
CREATE TRIGGER UpdateFieldABNotNull BEFORE UPDATE ON foo
FOR EACH ROW BEGIN
  IF (NEW.FieldA IS NULL AND NEW.FieldB IS NULL) THEN
    SIGNAL SQLSTATE '45000'
    SET MESSAGE_TEXT = '\'FieldA\' and \'FieldB\' cannot both be null';
  END IF;
END//
DELIMITER ;

INSERT INTO foo (FieldA, FieldB) VALUES (NULL, 10); -- OK
INSERT INTO foo (FieldA, FieldB) VALUES (10, NULL); -- OK
INSERT INTO foo (FieldA, FieldB) VALUES (NULL, NULL); -- gives error
UPDATE foo SET FieldA = NULL; -- gives error

2

यदि आप SQL सर्वर का उपयोग कर रहे हैं, तो आप अपनी तालिका में एक निरंतर गणना किए गए कॉलम का उपयोग करके ट्रिगर के उपयोग से बच सकते हैं:

CREATE TABLE Test_Constraint
(
    A DateTime Null,
    B DateTime Null,
    A_and_B AS (CASE WHEN A IS Null AND B IS Null THEN Null ELSE Convert(Binary(1), 1) END) PERSISTED Not Null 
);

गणना किए गए कॉलम A_and_B में केस स्टेटमेंट एक शून्य मान लौटाएगा यदि स्तंभ A और B दोनों शून्य हैं, लेकिन गणना किए गए कॉलम पर Not Null बाधा तब डालने से रोकने में कोई त्रुटि नहीं होगी। अन्यथा यह 1 लौटाता है।

चूंकि गणना किए गए कॉलम को बरकरार रखा गया है, इसलिए इसे तालिका में भौतिक रूप से संग्रहीत किया जाएगा। बाइनरी में कनवर्ट इस के प्रभाव को कम करता है, जिससे कॉलम 1 लंबाई का बाइनरी डेटाटाइप होता है।


1
SQL- सर्वर में, आप एक CHECKबाधा के साथ भी ऐसा कर सकते हैं । निरंतर कॉलम की कोई आवश्यकता नहीं है।
ypercube y

1
बहुत बढ़िया, यह थोड़ा साफ लगता है। CREATE TABLE Test_Constraint2 ( A DateTime Null, B DateTime Null, CONSTRAINT A_or_B_Not_Null CHECK (CASE WHEN A IS Null AND B IS Null THEN 0 ELSE 1 END = 1) )
शेन एस्टेले

बहुत बढ़िया जवाब! यह एक दूसरे की तुलना में अधिक उपयुक्त है, लेकिन जब से मैं MySQL का उपयोग कर रहा हूं, CHECK CLAUSE को पार्स किया जाता है, लेकिन MySQL पर ध्यान नहीं दिया जाता है, इसलिए मैं अन्य उत्तर को स्वीकार किए गए के रूप में चिह्नित करता हूं। +1
बार्ट कैलिक्सो

1

मुझे एक लेख मिला जो यहां एक ही चीज की तरह दिखता है

CREATE TABLE foo (
  FieldA INT,
  FieldB INT,
  FieldA_or_FieldB TINYINT NOT NULL;
);

DELIMITER //
CREATE TRIGGER FieldABNotNull BEFORE INSERT ON foo
FOR EACH ROW BEGIN
  IF (NEW.FieldA IS NULL AND NEW.FieldB IS NULL) THEN
    SET NEW.FieldA_or_FieldB = NULL;
  ELSE
    SET NEW.FieldA_or_FieldB = 1;
  END IF;
END//
DELIMITER ;

INSERT INTO foo (FieldA, FieldB) VALUES (NULL, 10); -- OK
INSERT INTO foo (FieldA, FieldB) VALUES (10, NULL); -- OK
INSERT INTO foo (FieldA, FieldB) VALUES (NULL, NULL); -- gives error

धन्यवाद, im का उपयोग कर MySQL और यह इसके साथ पूरी तरह से ठीक काम करता है। विशेष रूप से क्योंकि अशक्त स्तंभ त्रुटि पर एक शून्य मान फेंकने के कारण।
बार्ट कैलिक्सो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.