मैं SQL सर्वर के साथ कैस्केड डिलीट का उपयोग कैसे करूं?


332

मेरे पास 2 टेबल हैं: टी 1 और टी 2, वे डेटा के साथ मौजूदा टेबल हैं। T1 और T2 के बीच हमारे कई संबंध हैं। जब मैं T1 से रिकॉर्ड हटा दिया जाता है, तो T2 से जुड़े सभी रिकॉर्ड भी हटा दिए जाते हैं, तो मैं SQL सर्वर में कैस्केडिंग डिलीट करने के लिए टेबल परिभाषाओं को कैसे बदलूं।

उनके बीच विदेशी अड़चन है। मैं टेबल्स को हटाने या T2 के लिए डिलीट करने के लिए ट्रिगर बनाना नहीं चाहता। उदाहरण के लिए, जब मैं किसी कर्मचारी को हटाता हूं, तो सभी समीक्षा रिकॉर्ड भी चले जाने चाहिए।

T1 - कर्मचारी,

Employee ID      
Name
Status

T2 - प्रदर्शन समीक्षा,

Employee ID - 2009 Review
Employee ID - 2010 Review

जवाबों:


362

तुम्हें यह करना पड़ेगा,

  • मौजूदा विदेशी कुंजी बाधा को छोड़ें,
  • ON DELETE CASCADEसक्षम सेटिंग के साथ एक नया जोड़ें ।

कुछ इस तरह:

ALTER TABLE dbo.T2
   DROP CONSTRAINT FK_T1_T2   -- or whatever it's called

ALTER TABLE dbo.T2
   ADD CONSTRAINT FK_T1_T2_Cascade
   FOREIGN KEY (EmployeeID) REFERENCES dbo.T1(EmployeeID) ON DELETE CASCADE

3
मेरी टीम और मैंने बस यही किया। हमें अपनी बाधाओं को कम करना था और उन्हें जोड़ना था। यह हमारे लिए काम किया।
डेनियल एल वानडेनबॉश

2
यह हार्ड डिलीट के पक्ष में कैसे है? सॉफ्ट डिलीट में कभी भी बाधा नहीं होगी। मेरे बिल्कुल विपरीत लगता है।
मैक्स

2
@Maxx हार्ड डिलीट में, आप एक रिकॉर्ड हटाते हैं और अनाथ रजिस्टरों के बारे में चिंता करने की ज़रूरत नहीं है, जबकि सॉफ्ट डिलीट में आपको इसे मैन्युअल रूप से करने की आवश्यकता है।
रोनाल्डो

319

SQL सर्वर प्रबंधन स्टूडियो में मौजूदा विदेशी कुंजी के लिए "कैस्केड डिलीट" जोड़ने के लिए:

सबसे पहले, अपनी विदेशी कुंजी का चयन करें, और एक नई क्वेरी विंडो में "DROP और क्रिएट टू .." खोलें।

यहां छवि विवरण दर्ज करें

फिर, बस जोड़ने ON DELETE CASCADEके लिए ADD CONSTRAINTआदेश:

n और इस क्वेरी को चलाने के लिए "Execute" बटन दबाएं।

वैसे, अपनी विदेशी कुंजी की सूची प्राप्त करने के लिए, और देखें कि किन लोगों ने "कैस्केड डिलीट" चालू किया है, आप इस स्क्रिप्ट को चला सकते हैं:

SELECT 
   OBJECT_NAME(f.parent_object_id) AS 'Table name',
   COL_NAME(fc.parent_object_id,fc.parent_column_id) AS 'Field name',
   delete_referential_action_desc AS 'On Delete'
FROM sys.foreign_keys AS f,
     sys.foreign_key_columns AS fc,
     sys.tables t 
WHERE f.OBJECT_ID = fc.constraint_object_id
AND t.OBJECT_ID = fc.referenced_object_id
ORDER BY 1

और अगर आपको कभी पता चलता है कि आप DROPएक विदेशी कुंजी बाधा के कारण कोई विशेष तालिका नहीं बना सकते हैं , लेकिन आप यह नहीं समझ सकते हैं कि कौन सा FK समस्या पैदा कर रहा है, तो आप इस कमांड को चला सकते हैं:

sp_help 'TableName'

उस लेख में SQL सभी FK को सूचीबद्ध करता है जो एक विशेष तालिका को संदर्भित करता है।

आशा है कि यह सब मदद करता है।

लंबी उंगली के लिए क्षमा याचना। मैं सिर्फ एक बिंदु बनाने की कोशिश कर रहा था।


163

आप इसे SQL सर्वर प्रबंधन स्टूडियो के साथ कर सकते हैं।

→ टेबल डिज़ाइन पर राइट क्लिक करें और रिलेशनशिप पर जाएं और बाईं ओर के फलक पर और दाईं ओर के फलक में विदेशी कुंजी चुनें, मेनू "INSERT और UPDATE विनिर्देश" का विस्तार करें और "नियम" को हटाएं नियम के रूप में चुनें।

SQL सर्वर प्रबंधन स्टूडियो


नमस्ते, 4 के बीच क्या अंतर है, एक तालिका में सभी डेटा को हटाने के लिए आसान बनाने पर कैस्केड को चालू करता है। कैसे मैं सभी निर्भरता / FK कुंजी देख सकते हैं पर इस तालिका से नहीं इस तालिका,। सभी एफके को हटाने के बाद भी मुझे अभी भी एक त्रुटि मिलती है
एगी

@ इग्गी - आप निर्भरता की जांच कर सकते हैं - तालिका पर राइट क्लिक करें -> "डिपेंडेंसी देखें" इसके अलावा एसक्यूएल सर्वर आपको टेबल का नाम और कॉलम नाम के साथ विस्तृत त्रुटि देगा "इस DELETE स्टेटमेंट में REFERENC कसना" FK_Child1_Parent1 "के साथ विवादित है"। डेटाबेस "TESTDB", टेबल "dbo.Child1", कॉलम 'Parent1ID' में संघर्ष हुआ। "
पलानीकुमार 5

@aggie - इसके अलावा 4 वां मामला "सेट डिफॉल्ट" है, आपको फॉरेन की कॉलम में डिफॉल्ट कंस्ट्रक्शन सेट करना होगा, जब हम पेरेंट को हटा देंगे तब डिफॉल्ट वैल्यू को चाइल्ड टेबल में बदल दिया जाएगा। (नोट: डिफ़ॉल्ट मान मूल तालिका के साथ मेल खाना चाहिए।) अधिक जानकारी के लिए mssqltips.com/sqlservertip/2365/…
पलानीकुमार

यह बहुत मददगार है। मुझे आश्चर्य है, एक सम्मिलित नियम क्यों नहीं है? दूसरे शब्दों में, जब मैं T1 में एक पंक्ति जोड़ता हूं, तो मैं चाहता हूं कि T2 में संबंधित प्रविष्टि स्वचालित रूप से बनाई जाए।
राबर्ट एम।

@RobertM। क्योंकि इससे कोई मतलब नहीं है। यह कैसे पता चलेगा कि INSERT के लिए क्या मूल्य हैं? आप बच्चों की पंक्तियों को उत्पन्न करने के लिए INSERT ट्रिगर्स का उपयोग करने में सक्षम हो सकते हैं, उस पर शोध करने का प्रयास करें।
डेन बेचर

47

जैसे कुछ का उपयोग करें

ALTER TABLE T2
ADD CONSTRAINT fk_employee
FOREIGN KEY (employeeID)
REFERENCES T1 (employeeID)
ON DELETE CASCADE;

सही कॉलम नामों को भरें और आपको सेट किया जाना चाहिए। जैसा कि mark_s ने सही कहा है, यदि आपके पास पहले से ही एक विदेशी कुंजी बाधा है, तो आपको पहले पुराने को हटाना होगा और फिर नया बनाना होगा।


41
@marc_s - वास्तव में, आप दोनों तरफ एक ही कॉलम के खिलाफ दूसरी विदेशी कुंजी जोड़ सकते हैं, और यह सही ढंग से काम करेगा। यदि कोई डाउनटाइम के साथ उत्पादन के माहौल में काम कर रहा है, तो नए एफके को कैस्केड के साथ पेश करना बेहतर हो सकता है, और फिर पुराने एफके को छोड़ दें, जब कोई एफके जगह पर न हो तो मेज पर एक खिड़की छोड़ दें। (बस SQL ​​2008 पर परीक्षण किया गया)
Damien_The_Unbeliever

यह सही है। मैंने यह कोशिश की, और यह काम करता है। पहली विदेशी कुंजी बाधाओं को छोड़ने की कोई आवश्यकता नहीं है। उत्तर के लिए धन्यवाद।
बिचवन गुयेन जू

15

पहले ONCascade संपत्ति को सक्षम करने के लिए:

1. मौजूदा विदेशी कुंजी बाधा

2. पर एक नया एक के साथ सेट करें सक्षम सेटिंग सक्षम है

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

IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Response'))
 BEGIN 

ALTER TABLE [dbo].[Response] DROP CONSTRAINT [FK_Response_Request]  

ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

ELSE

 BEGIN 
 ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

ONCascade संपत्ति को निष्क्रिय करने के लिए दूसरा:

1. मौजूदा विदेशी कुंजी बाधा

2. पर एक नया एक DELETE NO ACTION सेटिंग सक्षम करें

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

IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Response'))
 BEGIN 
ALTER TABLE [dbo].[Response] DROP CONSTRAINT [FK_Response_Request]  

ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

ELSE

 BEGIN 
 ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE NO ACTION 
END

15

ON DELETE CASCADE
यह निर्दिष्ट करता है कि मूल डेटा हटाए जाने पर चाइल्ड डेटा हटा दिया जाता है।

CREATE TABLE products
( product_id INT PRIMARY KEY,
  product_name VARCHAR(50) NOT NULL,
  category VARCHAR(25)
);

CREATE TABLE inventory
( inventory_id INT PRIMARY KEY,
  product_id INT NOT NULL,
  quantity INT,
  min_level INT,
  max_level INT,
  CONSTRAINT fk_inv_product_id
    FOREIGN KEY (product_id)
    REFERENCES products (product_id)
    ON DELETE CASCADE
);

इस विदेशी कुंजी के लिए, हमने ON DELETE CASCADEक्लॉज़ को निर्दिष्ट किया है जो SQL सर्वर को चाइल्ड टेबल में संबंधित रिकॉर्ड को हटाने के लिए कहता है जब पैरेंट टेबल में डेटा डिलीट हो जाता है। इसलिए इस उदाहरण में, यदि product_id मान को उत्पाद तालिका से हटा दिया जाता है, तो इस उत्पाद का उपयोग करने वाले इन्वेंट्री टेबल में संबंधित रिकॉर्ड भी हटा दिए जाएंगे।


-2

यदि कई संबंधों में से एक T1 से T2 तक है, तो यह एक फ़ंक्शन का प्रतिनिधित्व नहीं करता है और इसलिए एक व्युत्क्रम फ़ंक्शन को घटाने या अनुमान लगाने के लिए उपयोग नहीं किया जा सकता है जो परिणामी T2 मान की गारंटी देता है T1 के tuples को छोड़ना T2 में शामिल नहीं होता है जो कटौती योग्य हैं , क्योंकि कोई कटौती योग्य मान्य उलटा कार्य नहीं है। (फ़ंक्शंस का प्रतिनिधित्व करना प्राथमिक कुंजी का उद्देश्य था।) एसक्यूएल थिंक का जवाब हां है आप इसे कर सकते हैं। रिलेशनल थिंक में जवाब है कि आप ऐसा नहीं कर सकते। कोडड 1970 में अस्पष्टता के बिंदु देखें। रिश्ते को T1 से T2 तक कई-से-एक होना होगा।


-10

मुझे लगता है कि आप तालिकाओं की संपत्ति को नष्ट नहीं कर सकते हैं यदि यह वास्तविक उत्पादन डेटा है, तो बस तालिका स्कीमा को प्रभावित करने वाली सामग्री को न हटाएं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.