Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

SQL सर्वर दूसरे फ़ील्ड ऑटो-इन्क्रीमेंट के साथ दो फ़ील्ड की अद्वितीय समग्र कुंजी

जब से किसी ने एक समान प्रश्न पोस्ट किया है, मैं इस पर विचार कर रहा हूं। पहली समस्या यह है कि डीबी "विभाजन योग्य" अनुक्रम प्रदान नहीं करते हैं (जो विभिन्न कुंजियों के आधार पर पुनरारंभ/याद रखेंगे)। दूसरा यह है कि SEQUENCE वे वस्तुएं जो हैं बशर्ते कि तेजी से पहुंच के लिए तैयार किया गया हो, और इसे वापस नहीं लाया जा सकता (यानी, आप करेंगे अंतराल प्राप्त करें)। यह अनिवार्य रूप से एक अंतर्निहित उपयोगिता का उपयोग करने से रोकता है... जिसका अर्थ है कि हमें अपना खुद का रोल करना होगा।

पहली चीज़ जो हमें चाहिए वह है हमारे अनुक्रम संख्याओं को संग्रहीत करने के लिए एक तालिका। यह काफी सरल हो सकता है:

CREATE TABLE Invoice_Sequence (base CHAR(1) PRIMARY KEY CLUSTERED,
                               invoiceNumber INTEGER);

वास्तव में base कॉलम एक विदेशी-कुंजी संदर्भ होना चाहिए, जो भी तालिका/आईडी उस व्यवसाय (ओं)/संस्थाओं को परिभाषित करती है जिनके लिए आप चालान जारी कर रहे हैं। इस तालिका में, आप चाहते हैं कि प्रविष्टियां प्रति जारी-इकाई के लिए अद्वितीय हों।

इसके बाद, आप एक संग्रहित खरीद चाहते हैं जो एक कुंजी (base . लेगी ) और क्रम में अगला नंबर थूक दें (invoiceNumber ) आवश्यक चाबियों का सेट अलग-अलग होगा (यानी, कुछ चालान संख्याओं में वर्ष या जारी होने की पूरी तारीख होनी चाहिए), लेकिन इस स्थिति के लिए आधार प्रपत्र इस प्रकार है:

CREATE PROCEDURE Next_Invoice_Number @baseKey CHAR(1), 
                                     @invoiceNumber INTEGER OUTPUT 
AS MERGE INTO Invoice_Sequence Stored
              USING (VALUES (@baseKey)) Incoming(base)
                 ON Incoming.base = Stored.base
   WHEN MATCHED THEN UPDATE SET Stored.invoiceNumber = Stored.invoiceNumber + 1
   WHEN NOT MATCHED BY TARGET THEN INSERT (base) VALUES(@baseKey)
   OUTPUT INSERTED.invoiceNumber ;;

ध्यान दें कि:

  1. आपको होना चाहिए इसे क्रमबद्ध लेनदेन में चलाएं
  2. लेन-देन होना चाहिए वही हो जो गंतव्य (चालान) तालिका में सम्मिलित कर रहा है।

यह सही है, इनवॉइस नंबर जारी करते समय भी आप प्रति-व्यवसाय को अवरुद्ध करते रहेंगे। आप नहीं इससे बचें यदि चालान संख्या अनुक्रमिक होनी चाहिए, बिना किसी अंतराल के - जब तक कि पंक्ति वास्तव में प्रतिबद्ध नहीं हो जाती, तब तक इसे वापस लाया जा सकता है, जिसका अर्थ है कि चालान संख्या जारी नहीं की गई होगी।

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

CREATE TRIGGER Populate_Invoice_Number ON Invoice INSTEAD OF INSERT
AS 
  DECLARE @invoiceNumber INTEGER
  BEGIN
    EXEC Next_Invoice_Number Inserted.base, @invoiceNumber OUTPUT
    INSERT INTO Invoice (base, invoiceNumber) 
                VALUES (Inserted.base, @invoiceNumber)
  END

(जाहिर है, आपके पास और कॉलम हैं, जिनमें अन्य कॉलम भी शामिल हैं जिन्हें ऑटो-पॉप्युलेट किया जाना चाहिए - आपको उन्हें भरना होगा)
...जिसे आप केवल यह कहकर उपयोग कर सकते हैं:

INSERT INTO Invoice (base) VALUES('A');

तो हमने क्या किया है? अधिकतर, यह सारा काम लेन-देन द्वारा बंद पंक्तियों की संख्या को कम करने के बारे में था। इस तक INSERT प्रतिबद्ध है, केवल दो पंक्तियाँ लॉक हैं:

  • पंक्ति Invoice_Sequence . में क्रम संख्या बनाए रखना
  • Invoice में पंक्ति नए चालान के लिए।

किसी विशेष base . के लिए अन्य सभी पंक्तियां स्वतंत्र हैं - उन्हें अपनी इच्छा से अद्यतन या पूछताछ की जा सकती है (इस तरह की प्रणाली से जानकारी को हटाने से एकाउंटेंट परेशान हो जाते हैं)। आपको शायद यह तय करना होगा कि क्या होना चाहिए जब प्रश्नों में सामान्य रूप से लंबित चालान शामिल होंगे...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर में एक साथ कई कॉलम कैसे बदलें

  2. SQL सर्वर (T-SQL) में 'स्मॉलडेटटाइम' को 'डेटाटाइम' में बदलने के उदाहरण

  3. सीएसवी डेटा के भीतर अल्पविराम

  4. आपके SQL सर्वर जटिलता को कम करने के लिए युक्तियाँ

  5. तालिका बनाने के 2 तरीके यदि यह SQL सर्वर में मौजूद नहीं है