2010-07-30 11 views
6

मैं एकाधिक कॉलम पर एक समग्र कुंजी कैसे बना सकता हूं, जिनमें से एक में कुछ मूल्य हो सकता है लेकिन शून्य (या कुछ स्थिर मूल्य) नहीं हो सकता है?एकाधिक कॉलम पर एक समग्र कुंजी कैसे बनाएं

उदाहरण के लिए:

PK Loc_ID  Date    Time  Cancelled 
1   1   01/01/2010  10:00AM  YES 
2   1   01/01/2010  10:00AM  YES 
3   1   01/01/2010  10:00AM  null 
4   1   01/01/2010  10:00AM  null - Not Acceptable 

चौथे रिकॉर्ड की प्रविष्टि एक समग्र कुंजी उल्लंघन त्रुटि उठाना चाहिए।

+3

आपका उदाहरण डेटा पीके = 4 के साथ पंक्ति को अस्वीकार करने का कोई आधार नहीं देता है जब यह पीके = 2. –

+0

@ जोनाथन लेफ्लर के साथ किसी को भी अस्वीकार नहीं करता है - मुझे इसे मारो। वही सवाल था। – Thomas

+0

हां, पीके = 2 ठीक है। रद्द किए गए किसी भी मूल्य का हो सकता है लेकिन एक ही स्थान, दिनांक और समय के लिए दो बार दोहराना नहीं। –

उत्तर

6

तो आप क्या क्या एक नियम है, जहां केवल रिकॉर्ड LOC_ID, तिथि, समय के किसी भी दिए गए क्रमपरिवर्तन के लिए रद्द नहीं किया जा सकता है लागू करने के लिए है? हम इसे फ़ंक्शन-आधारित अद्वितीय अनुक्रमणिका के साथ कर सकते हैं।

SQL> select * from t34 
    2/

     PK  LOC_ID SOMEDATE SOMETIM CAN 
---------- ---------- ---------- ------- --- 
     1   1 01/01/2010 10:00AM YES 
     2   1 01/01/2010 10:00AM YES 
     3   1 01/01/2010 10:00AM 

SQL> insert into t34 
    2 values (4 , 1 , to_date('01/01/2010','DD/MM/YYYY') , '10:00AM', null) 
    3/

1 row created. 

SQL> 

के शासन लागू करने के लिए

SQL> rollback 
    2/

Rollback complete. 

SQL> create unique index t34_uidx 
    2 on t34 (loc_id, somedate, some_time, nvl2(cancelled, pk, null)) 
    3/

Index created. 

SQL> 

NVL2() समारोह एक सूचकांक का निर्माण करते हैं है जो दूसरा तर्क है, तो रिटर्न मामले की एक विशेष रूप:

इसी को हम बचना चाहते है पहला तर्क न तो तीसरा है। सूचकांक दूसरे तर्क के रूप में पीके कोल का उपयोग करता है क्योंकि यह प्राथमिक कुंजी है और इसलिए अद्वितीय है। तो सूचकांक रद्द की डुप्लिकेट मानों की अनुमति देता है जब तक कि वे अशक्त हैं:

SQL> insert into t34 
    2 values (4 , 1 , to_date('01/01/2010','DD/MM/YYYY') , '10:00AM', null) 
    3/
insert into t34 values (4 , 1 , to_date('01/01/2010','DD/MM/YYYY') , '10:00AM', null) 
* 
ERROR at line 1: 
ORA-00001: unique constraint (APC.T34_UIDX) violated 


SQL> 
+0

वाह! यह काम। धन्यवाद। –

0

मुझे यकीन नहीं है कि यह ओरेकल में मान्य है, लेकिन पोस्टग्रेस्क्ल में आप शून्य पर आंशिक मल्टीकॉलम इंडेक्स के साथ ऐसा कर सकते हैं, जो कि शून्य है।

CREATE UNIQUE INDEX idx_foo 
ON example (Loc_ID, Date, Time) 
WHERE canceled IS NULL 
+0

नहीं, 'पंक्ति 2' 'रद्द' शून्य नहीं है, यह पूर्ण पर आंशिक अनुक्रमणिका है। मैं काफी हद तक निश्चित हूं कि आप इसे ओरेकल में कर सकते हैं, मुझे नहीं पता कि कैसे, और सोचा कि यह उत्तर के लिए अच्छा जोड़ा जा सकता है। –

+0

दाएं। वह देखा। मेरा मानना ​​है कि एसक्यूएल 2008 भी इस धारणा का समर्थन करता है लेकिन मुझे नहीं लगता कि ओरेकल अभी तक करता है। – Thomas

+0

मुझे ऐसा नहीं लगता, मुझे लगता है कि यह शायद एसक्यूएल 99 है। पोस्टग्रेस्क्ल ने इसे कम से कम 8 वर्षों तक समर्थन दिया है। –

1

क्या यह एक अद्वितीय कार्य आधारित इंडेक्स के साथ किया जा सकता है? की तरह कुछ:

create unique index ix on tb (
    loc_id, date, time, decode(cancelled, null, 1, null)); 
+0

में उन्हें कैसे करें, रद्द करने के मामलों के लिए ओरेकल में काम नहीं करेगा, loc_id, date के समान संयोजन के लिए 'हां' , पहर। –

+0

एनवी 2() के साथ एपीसी का संस्करण क्लीनर है, और स्पष्ट रूप से काम करता है, जबकि यह अनचाहे है।सिर्फ अपने ही फायदे के लिए, मैं शून्य, प्रभावी ढंग से उलट रहा हूं, जो एक ही इरादे के बारे में है; लेकिन शायद 'डीकोड (रद्द, शून्य, <कुछ जादू मूल्य>, पीके) किया जाना चाहिए था। जहां जादू मूल्य कुछ भी हो सकता है 'पीके' कभी नहीं होगा। जो खुद में स्पष्ट रूप से खतरनाक है, इसलिए ... –

1

नियम यह है कि केवल एक शून्य LOC_ID, DATE_COL, और TIME_COL की एक विशेष संयोजन के लिए रद्द कर दिया मूल्य है:

SQL> create table EXAMPLE 
    2 ( PK  number  not null, 
    3  LOC_ID number  not null, 
    4  DATE_COL date   null, 
    5  TIME_COL varchar2(10) null, 
    6  CANCELLED varchar2(3) null, 
    7  constraint EXAMPLE_PK primary key (PK) 
    8 ); 

Table created. 

SQL> 
SQL> create unique index EXAMPLE_UK01 on EXAMPLE 
    2 (case when CANCELLED is null then LOC_ID else null end, 
    3  case when CANCELLED is null then DATE_COL else null end, 
    4  case when CANCELLED is null then TIME_COL else null end 
    5 ); 

Index created. 

SQL> 
SQL> INSERT INTO EXAMPLE VALUES 
    2 (1, 1, DATE '2010-01-01', '10:00AM', 'YES'); 

1 row created. 

SQL> 
SQL> INSERT INTO EXAMPLE VALUES 
    2 (2, 1, DATE '2010-01-01', '10:00AM', 'YES'); 

1 row created. 

SQL> 
SQL> INSERT INTO EXAMPLE VALUES 
    2 (3, 1, DATE '2010-01-01', '10:00AM', null); 

1 row created. 

SQL> 
SQL> INSERT INTO EXAMPLE VALUES 
    2 (4, 1, DATE '2010-01-01', '10:00AM', null); 
INSERT INTO EXAMPLE VALUES 
* 
ERROR at line 1: 
ORA-00001: unique constraint ([schema].EXAMPLE_UK01) violated