खैर, इस प्रकार के कॉलम के लिए कोई मूल समर्थन नहीं है, लेकिन आप इसे ट्रिगर का उपयोग करके लागू कर सकते हैं:
CREATE TRIGGER tr_MyTable_Number
ON MyTable
INSTEAD OF INSERT
AS
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN;
WITH MaxNumbers_CTE AS
(
SELECT ParentEntityID, MAX(Number) AS Number
FROM MyTable
WHERE ParentEntityID IN (SELECT ParentEntityID FROM inserted)
)
INSERT MyTable (ParentEntityID, Number)
SELECT
i.ParentEntityID,
ROW_NUMBER() OVER
(
PARTITION BY i.ParentEntityID
ORDER BY (SELECT 1)
) + ISNULL(m.Number, 0) AS Number
FROM inserted i
LEFT JOIN MaxNumbers_CTE m
ON m.ParentEntityID = i.ParentEntityID
COMMIT
परीक्षण नहीं किया गया लेकिन मुझे पूरा यकीन है कि यह काम करेगा। यदि आपके पास प्राथमिक कुंजी है, तो आप इसे AFTER
. के रूप में भी लागू कर सकते हैं ट्रिगर (मुझे INSTEAD OF
का उपयोग करना पसंद नहीं है ट्रिगर, उन्हें समझना कठिन होता है जब आपको उन्हें 6 महीने बाद संशोधित करने की आवश्यकता होती है)।
यहाँ क्या हो रहा है यह समझाने के लिए:
-
SERIALIZABLE
सख्त अलगाव मोड है; यह गारंटी देता है कि एक समय में केवल एक डेटाबेस लेनदेन इन कथनों को निष्पादित कर सकता है, जिसकी हमें इस "अनुक्रम" की अखंडता की गारंटी के लिए आवश्यकता है। ध्यान दें कि यह अपरिवर्तनीय रूप से संपूर्ण लेन-देन को बढ़ावा देता है, इसलिए आप लंबे समय से चल रहे लेन-देन के अंदर इसका उपयोग नहीं करना चाहेंगे। -
सीटीई प्रत्येक पैरेंट आईडी के लिए पहले से उपयोग की गई उच्चतम संख्या को चुनता है;
-
ROW_NUMBER
प्रत्येक पैरेंट आईडी के लिए एक अद्वितीय अनुक्रम उत्पन्न करता है (PARTITION BY
) नंबर 1 से शुरू; यदि नया अनुक्रम प्राप्त करने के लिए कोई है तो हम इसे पिछले अधिकतम में जोड़ देते हैं।
मुझे शायद यह भी उल्लेख करना चाहिए कि यदि आपको एक समय में केवल एक नई बाल इकाई डालने की आवश्यकता है, तो आप ट्रिगर का उपयोग करने के बजाय संग्रहीत प्रक्रिया के माध्यम से उन परिचालनों को फ़नल करने से बेहतर हैं - आपको निश्चित रूप से इससे बेहतर प्रदर्शन मिलेगा . यह वर्तमान में hierarchyid
. के साथ इस प्रकार किया जाता है SQL '08 में कॉलम।