DELETE कथन ने संदर्भ बाधा के साथ विरोध किया


11

मैं सभी उपयोगकर्ताओं को हटाने की कोशिश कर रहा हूं लेकिन त्रुटि हो रही है:

Msg 547, Level 16, State 0, Line 1
The DELETE statement conflicted with the REFERENCE constraint "FK_M02ArticlePersons_M06Persons". The conflict occurred in database "workdemo.no", table "dbo.M02ArticlePersons", column 'M06PersonId'.
The statement has been terminated.

पूछताछ:

DELETE FROM [workdemo.no].[dbo].[M06Persons] 
WHERE ID > '13'
GO

लगता है कि मुझे उपयोग करने की आवश्यकता है on delete cascade;लेकिन मैं फंस गया हूं।

जवाबों:


18

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

अब जाकर उस व्यक्ति के साथ बात करें, जिसने स्कीमा को डिज़ाइन किया है और बाधाओं को जानता है और उससे पूछता है कि आप उन अभिलेखों को ठीक से कैसे हटाएं जिन्हें आप सही क्रम में हटा रहे हैं और डेटाबेस को सुसंगत रखने के लिए उचित सावधानी बरत रहे हैं।


9

आपके पास यहां दो वास्तविक विकल्प हैं, आप टेबल पर बाधाओं को अक्षम कर सकते हैं। यह आमतौर पर एक महान विचार नहीं है क्योंकि आप एक खराब डेटा स्थिति के साथ समाप्त हो सकते हैं यदि आप उन डेटा के साथ खिलवाड़ कर रहे हैं जो अन्य तालिकाओं से संबंधित हैं, लेकिन अपने स्कीमा की पूरी सीमा नहीं जानते हैं और यह आपके उद्देश्यों के अनुरूप हो सकता है:

ALTER TABLE [workdemo.no].[dbo].[M06Persons] NOCHECK CONSTRAINT [FK_M02ArticlePersons_M06Persons]

हटाने के बाद बाधा को वापस चालू करने के लिए याद रखें

ALTER TABLE [workdemo.no].[dbo].[M06Persons] WITH CHECK CHECK CONSTRAINT [FK_M02ArticlePersons_M06Persons]

दूसरी पसंद का उपयोग करते हुए ON DELETE CASCADE विकल्प के साथ बाधा को छोड़ना और फिर से जोड़ना होगा:

ALTER TABLE [workdemo.no].[dbo].[M06Persons] DROP CONSTRAINT [FK_M02ArticlePersons_M06Persons]

ALTER TABLE [workdemo.no].[dbo].[M06Persons] WITH NOCHECK ADD CONSTRAINT [FK_M02ArticlePersons_M06Persons] FOREIGN KEY(M06PersonId)
REFERENCES <parent table here> (<parent column here>)
ON DELETE CASCADE

आपके FK नाम के आधार पर ऐसा लगता है कि आपकी मूल तालिका M02ArticlePersons है और मूल स्तंभ M06Ponsons है।

यदि आपने इस स्कीमा को अधिकृत नहीं किया है, तो कृपया इस पर विचार करने का प्रयास करें कि बाधाएं क्यों हो सकती हैं, और यह समझें कि इस तरह से उनका उल्लंघन करने से अनपेक्षित दुष्प्रभाव हो सकते हैं।


2

स्तंभ M06PersonId की dbo.M02ArticlePersons तालिका दूसरी तालिका में रखी गई है। इसलिए स्टेटमेंट डिलीट करने से पहले इस रिलेशनशिप को डिसेबल कर दें और दोबारा कोशिश करें

नीचे विदेशी कुंजी को अस्वीकार करने के लिए है

 ALTER TABLE dbo.M02ArticlePersons NOCHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

DELETE FROM [workdemo.no].[dbo].[M06Persons] 
  WHERE ID > '13'
GO

और इसे सक्षम करना है

ALTER TABLE dbo.M02ArticlePersons CHECK CONSTRAINT FK_M02ArticlePersons_M06Persons

उम्मीद है कि यह काम करेगा


2
भयानक सुझाव। आपको कभी भी एक FK बाधा को निष्क्रिय नहीं करना चाहिए क्योंकि आप एक वरिष्ठ dba हैं (जो कि आपने ऊपर लिखित प्रश्न नहीं लिखा होगा)। उन बाधाओं को आप रिकॉर्ड को हटाने से रोकने के लिए हैं। उन्हें विली नीली अक्षम करने से आपके डेटाबेस में खराब डेटा मिलेगा। आप एक अच्छा नहीं एक सबसे खराब अभ्यास फिर से शुरू कर रहे हैं।
HLGEM

1

एक और मैनुअल विकल्प भी है:

आप चाइल्ड टेबल पर जा सकते हैं और पैरेंट कुंजी द्वारा संदर्भित चाइल्ड रो को हटा सकते हैं। तब आप मूल पंक्ति को हटा सकते हैं। यह अनिवार्य रूप से कैस्केड हटाता है। इस तरह, आपको अपने अवरोधों को छोड़ना / फिर से बदलना / बदलना नहीं है।


1

यह छोटा कोड किसी भी तालिका के लिए मदद करेगा जिसे आप रिकॉर्ड से हटाना चाहते हैं। यह संदर्भात्मक अखंडता का ख्याल रखता है ...

नीचे दिए गए कोड से DELETE स्टेटमेंट जेनरेट होगा .. बस स्कीमा टाइप करें

Declare @sql1 varchar(max)
      , @ptn1 varchar(200)
      , @ctn1 varchar(200)
      , @ptn2 varchar(200)
      , @ctn2 varchar(200)
--
SET @ptn1 = ''
--
SET @ctn1 = ''
--
SET @ptn2 = ''
--
SET @ctn2 = ''
--
SELECT @sql1 = case when (@ptn1 <> OBJECT_NAME (f.referenced_object_id)) then
                         COALESCE( @sql1 + char(10), '') + 'DELETE' + char(10) + ' ' + OBJECT_NAME (f.referenced_object_id) + ' FROM ' + OBJECT_NAME(f.parent_object_id) + ', '+OBJECT_NAME (f.referenced_object_id) + char(10) +' WHERE ' + OBJECT_NAME(f.parent_object_id) + '.' + COL_NAME(fc.parent_object_id, fc.parent_column_id) +'='+OBJECT_NAME (f.referenced_object_id)+'.'+COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
                    else
                         @sql1 + ' AND ' + OBJECT_NAME(f.parent_object_id) + '.' + COL_NAME(fc.parent_object_id, fc.parent_column_id) +'='+OBJECT_NAME (f.referenced_object_id)+'.'+COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
                    end + char(10)
     , @ptn1 = OBJECT_NAME (f.referenced_object_id)
     , @ptn2  = object_name(f.parent_object_id)
FROM   sys.foreign_keys AS f
       INNER JOIN
       sys.foreign_key_columns AS fc ON f.object_id = fc.constraint_object_id
WHERE  f.parent_object_id = OBJECT_ID('dbo.M06Persons'); -- CHANGE here schema.table_name
--
print  '--Table Depended on ' + @ptn2 + char(10) + @sql1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.