SQL DROP टेबल विदेशी कुंजी बाधा


154

अगर मैं अपने डेटाबेस की सभी तालिकाओं को इस तरह हटाना चाहता हूं, तो क्या यह विदेशी कुंजी बाधा का ख्याल रखेगा? यदि नहीं, तो मैं पहले कैसे ध्यान रखूं?

GO
IF OBJECT_ID('dbo.[Course]','U') IS NOT NULL
    DROP TABLE dbo.[Course]
GO
IF OBJECT_ID('dbo.[Student]','U') IS NOT NULL
    DROP TABLE dbo.[Student]


2
इस उत्तर की जाँच करें, इसने मेरी मदद की;) stackoverflow.com/a/5488670/2205144
xatz

जवाबों:


335

नहीं, यह आपकी तालिका को नहीं गिराएगा यदि वास्तव में विदेशी कुंजी इसे संदर्भित कर रहे हैं।

अपनी तालिका को संदर्भित करने वाले सभी विदेशी प्रमुख संबंधों को प्राप्त करने के लिए, आप इस एसक्यूएल का उपयोग कर सकते हैं (यदि आप एसक्यूएल सर्वर 2005 और ऊपर हैं):

SELECT * 
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('Student')

और यदि कोई हो, तो इस कथन के साथ, आप वास्तव में उन FK संबंधों को छोड़ने के लिए SQL कथन बना सकते हैं:

SELECT 
    'ALTER TABLE [' +  OBJECT_SCHEMA_NAME(parent_object_id) +
    '].[' + OBJECT_NAME(parent_object_id) + 
    '] DROP CONSTRAINT [' + name + ']'
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('Student')

नोट: उत्पन्न तालिका में अलग-अलग क्वेरी में चलाने के लिए अलग-अलग बाधाओं को हटाने के लिए कथन हैं। इसने मेरे मामले में अद्भुत काम किया क्योंकि मुझे बेकार टेबल (परीक्षण उद्देश्यों के लिए) से छुटकारा पाने की आवश्यकता थी, जबकि बाकी तालिकाएं जो इसे बरकरार रखती थीं।
मौरिसियो क्विंटाना

1
मुझे संदर्भित_object_id के बजाय parent_object_id का उपयोग करना पड़ा
टॉम रॉबिन्सन

2
सभी संदर्भ तालिकाओं को प्राप्त करने के लिए SELECT स्टेटमेंट का एक विकल्प है: EXEC sp_fkeys 'Student';
बुग्गीबॉय

छोटा समायोजन यह क्वेरी 'ALTER TABLE' + OBJECT_SCHEMA_NAME (parent_object_id) + 'का चयन करें। [+] CONSTRAINT नाम के साथ
Stas Svishov

1
एक चर के रूप में अपने अंतिम चयन को कैसे असाइन करें और इसे निष्पादित करें?
हृदयोज टी।

44

SQL सर्वर प्रबंधन स्टूडियो 2008 (R2) और नए में, आप राइट क्लिक कर सकते हैं

DB -> कार्य -> ​​लिपियां उत्पन्न करें

  • उन तालिकाओं का चयन करें जिन्हें आप DROP करना चाहते हैं।

  • "नई क्वेरी विंडो में सहेजें" का चयन करें।

  • उन्नत बटन पर क्लिक करें।

  • स्क्रिप्ट DROP सेट करें और स्क्रिप्ट DROP में बनाएँ।

  • सही करने के लिए स्क्रिप्ट विदेशी कुंजी सेट करें।

  • ओके पर क्लिक करें।

  • अगला -> अगला -> समाप्त पर क्लिक करें।

  • स्क्रिप्ट देखें और फिर निष्पादित करें।


12
अभी भी वही 'ऑब्जेक्ट my_table' नहीं छोड़ सका क्योंकि यह एक FOREIGN कुंजी बाधा द्वारा संदर्भित है।
FrenkyB

6
इस उत्तर का
28+

1
हालांकि यह स्क्रिप्ट उत्पन्न करता है - वह स्क्रिप्ट समस्या को हल नहीं करता है, जो कि विदेशी कुंजी बाधाओं द्वारा संदर्भित तालिका को छोड़ देता है।
एलेक्सी श्वेलेव

मेरे लिए एक जादू की तरह काम किया।
जोहान

21

यदि आप पहले "बच्चे" तालिका को छोड़ देते हैं, तो विदेशी कुंजी को भी छोड़ दिया जाएगा। यदि आप पहले "पैरेंट" तालिका को छोड़ने का प्रयास करते हैं, तो आपको "ऑब्जेक्ट ड्रॉप नहीं कर सकता है 'ए' क्योंकि यह एक फॉरेस्ट कुंजी बाधा द्वारा संदर्भित है।" त्रुटि।


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

4
सच है, और एक समाधान अगर लक्ष्य है, जैसा कि कहा गया है, "अगर मैं अपने डेटाबेस में सभी तालिकाओं को हटाना चाहता हूं ..."
फिलिप केली

4
यह स्वीकार किए गए एक से बेहतर उत्तर है, जिसे देखते हुए प्रश्नकर्ता "मेरे डेटाबेस में सभी तालिकाओं को हटाना चाहता है"
lukkea

17

sp_MSdropconstraintsप्रक्रिया का उपयोग करके सभी तालिकाओं को सही ढंग से छोड़ने का एक और तरीका है । सबसे छोटा कोड जो मैं सोच सकता था:

exec sp_MSforeachtable "declare @name nvarchar(max); set @name = parsename('?', 1); exec sp_MSdropconstraints @name";
exec sp_MSforeachtable "drop table ?";

बहुत बढ़िया आदमी …………
edCoder

2

यदि यह SQL सर्वर है, तो आपको तालिका को छोड़ने से पहले बाधा को छोड़ना होगा।


2

@Mark_s ने जो कुछ पोस्ट किया है, उससे थोड़ा अधिक सामान्य संस्करण, इससे मुझे मदद मिली

SELECT 
'ALTER TABLE ' +  OBJECT_SCHEMA_NAME(k.parent_object_id) +
'.[' + OBJECT_NAME(k.parent_object_id) + 
'] DROP CONSTRAINT ' + k.name
FROM sys.foreign_keys k
WHERE referenced_object_id = object_id('your table')

बस अपना तालिका नाम प्लग करें, और उसके परिणाम को निष्पादित करें।


1
नमस्ते, मैं ऊपर से अपनी विदेशी कुंजी बाधाओं को छोड़ने की कोशिश कर रहा हूं, लेकिन जब मैं एक तालिका को बाद में छोड़ने के लिए जाता हूं, तो यह कहता है कि "वस्तु को नहीं गिरा सकता क्योंकि यह अभी भी एक विदेशी कुंजी बाधा द्वारा संदर्भित किया जा रहा है ... किसी भी विचार? अग्रिम धन्यवाद।
daniness

1

यहाँ एक और तरीका है कि तालिकाओं के बाद आने वाली सभी बाधाओं को दूर करने के लिए, एक सम्मिश्रण चाल का उपयोग करके FOR XML PATH('') जो एक इनपुट आउटपुट पंक्ति में कई इनपुट पंक्तियों को विलय करने की अनुमति देता है। SQL 2005 और बाद में कुछ भी काम करना चाहिए।

मैंने सुरक्षा के लिए बाहर की गई टिप्पणियों को छोड़ दिया है।

DECLARE @SQL NVARCHAR(max)
;WITH fkeys AS (
    SELECT quotename(s.name) + '.' + quotename(o.name) tablename, quotename(fk.name) constraintname 
    FROM sys.foreign_keys fk
    JOIN sys.objects o ON fk.parent_object_id = o.object_id
    JOIN sys.schemas s ON o.schema_id = s.schema_id
)
SELECT @SQL = STUFF((SELECT '; ALTER TABLE ' + tablename + ' DROP CONSTRAINT ' + constraintname
FROM fkeys
FOR XML PATH('')),1,2,'')

-- EXECUTE(@sql)

SELECT @SQL = STUFF((SELECT '; DROP TABLE ' + quotename(TABLE_SCHEMA) + '.' + quotename(TABLE_NAME) 
FROM INFORMATION_SCHEMA.TABLES 
FOR XML PATH('')),1,2,'')

-- EXECUTE(@sql)

यह अच्छी तरह से काम नहीं करता है क्योंकि सभी एफके को नहीं छोड़ा जाएगा (केवल उन जहां हमारी तालिका को माता-पिता के रूप में उपयोग किया जाता है, जहां हमें भी बाधा डालना चाहिए जहां हमारी तालिका "संदर्भित" के रूप में उपयोग की गई थी)।
रोमन पोक्रोव्सीज

रोमन, मूल पोस्ट विदेशी प्रमुख बाधाओं को हटाने के बारे में है। मेरा जवाब उस से परे कुछ भी कवर करने का लक्ष्य नहीं रखता।
वारेन रमक

1

समाधान को लागू करने के लिए एक पूरी स्क्रिप्ट यहां दी गई है:

create Procedure [dev].DeleteTablesFromSchema
(
    @schemaName varchar(500)
)
As 
begin
    declare @constraintSchemaName nvarchar(128), @constraintTableName nvarchar(128),  @constraintName nvarchar(128)
    declare @sql nvarchar(max)
    -- delete FK first
    declare cur1 cursor for
    select distinct 
    CASE WHEN t2.[object_id] is NOT NULL  THEN  s2.name ELSE s.name END as SchemaName,
    CASE WHEN t2.[object_id] is NOT NULL  THEN  t2.name ELSE t.name END as TableName,
    CASE WHEN t2.[object_id] is NOT NULL  THEN  OBJECT_NAME(d2.constraint_object_id) ELSE OBJECT_NAME(d.constraint_object_id) END as ConstraintName
    from sys.objects t 
        inner join sys.schemas s 
            on t.[schema_id] = s.[schema_id]
        left join sys.foreign_key_columns d 
            on  d.parent_object_id = t.[object_id]
        left join sys.foreign_key_columns d2 
            on  d2.referenced_object_id = t.[object_id]
        inner join sys.objects t2 
            on  d2.parent_object_id = t2.[object_id]
        inner join sys.schemas s2 
            on  t2.[schema_id] = s2.[schema_id]
    WHERE t.[type]='U' 
        AND t2.[type]='U'
        AND t.is_ms_shipped = 0 
        AND t2.is_ms_shipped = 0 
        AND s.Name=@schemaName
    open cur1
    fetch next from cur1 into @constraintSchemaName, @constraintTableName, @constraintName
    while @@fetch_status = 0
    BEGIN
        set @sql ='ALTER TABLE ' + @constraintSchemaName + '.' + @constraintTableName+' DROP CONSTRAINT '+@constraintName+';'
        exec(@sql)
        fetch next from cur1 into @constraintSchemaName, @constraintTableName, @constraintName
    END
    close cur1
    deallocate cur1

    DECLARE @tableName nvarchar(128)
    declare cur2 cursor for
    select s.Name, p.Name
    from sys.objects p
        INNER JOIN sys.schemas s ON p.[schema_id] = s.[schema_id]
    WHERE p.[type]='U' and is_ms_shipped = 0 
    AND s.Name=@schemaName
    ORDER BY s.Name, p.Name
    open cur2

    fetch next from cur2 into @schemaName,@tableName
    while @@fetch_status = 0
    begin
        set @sql ='DROP TABLE ' + @schemaName + '.' + @tableName
        exec(@sql)
        fetch next from cur2 into @schemaName,@tableName
    end

    close cur2
    deallocate cur2

end
go

1
Removing Referenced FOREIGN KEY Constraints
Assuming there is a parent and child table Relationship in SQL Server:

--First find the name of the Foreign Key Constraint:
  SELECT * 
  FROM sys.foreign_keys
  WHERE referenced_object_id = object_id('States')

--Then Find foreign keys referencing to dbo.Parent(States) table:
   SELECT name AS 'Foreign Key Constraint Name', 
           OBJECT_SCHEMA_NAME(parent_object_id) + '.' + OBJECT_NAME(parent_object_id) AS 'Child Table'
   FROM sys.foreign_keys 
   WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'dbo' AND 
              OBJECT_NAME(referenced_object_id) = 'dbo.State'

 -- Drop the foreign key constraint by its name 
   ALTER TABLE dbo.cities DROP CONSTRAINT FK__cities__state__6442E2C9;

 -- You can also use the following T-SQL script to automatically find 
 --and drop all foreign key constraints referencing to the specified parent 
 -- table:

 BEGIN

DECLARE @stmt VARCHAR(300);

-- Cursor to generate ALTER TABLE DROP CONSTRAINT statements  
 DECLARE cur CURSOR FOR
 SELECT 'ALTER TABLE ' + OBJECT_SCHEMA_NAME(parent_object_id) + '.' + 
 OBJECT_NAME(parent_object_id) +
                ' DROP CONSTRAINT ' + name
 FROM sys.foreign_keys 
 WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'dbo' AND 
            OBJECT_NAME(referenced_object_id) = 'states';

 OPEN cur;
 FETCH cur INTO @stmt;

 -- Drop each found foreign key constraint 
  WHILE @@FETCH_STATUS = 0
  BEGIN
    EXEC (@stmt);
    FETCH cur INTO @stmt;
  END

  CLOSE cur;
  DEALLOCATE cur;

  END
  GO

--Now you can drop the parent table:

 DROP TABLE states;
--# Command(s) completed successfully.

0

SQL सर्वर मैनेजर का उपयोग करके आप UI से विदेशी प्रमुख बाधाओं को छोड़ सकते हैं। यदि आप तालिका को हटाना चाहते हैं, Diaryलेकिन उपयोगकर्ता तालिका में तालिका की DiaryIdओर इशारा करते हुए एक विदेशी कुंजी है Diary, तो आप तालिका का विस्तार (प्लस प्रतीक का उपयोग करके) कर सकते Userहैं और फिर Foreign Keysअनुभाग का विस्तार कर सकते हैं । उस विदेशी कुंजी पर राइट क्लिक करें जो डायरी तालिका की ओर इशारा करती है Delete। फिर आप Columnsअनुभाग का विस्तार कर सकते हैं , राइट क्लिक करें और कॉलम को DiaryIdभी हटा सकते हैं। तब आप बस चला सकते हैं:

drop table Diary

मुझे पता है कि आपका वास्तविक प्रश्न सभी तालिकाओं को हटाने के बारे में है, इसलिए यह उस मामले के लिए उपयोगी नहीं हो सकता है। हालाँकि, यदि आप केवल कुछ तालिकाओं को हटाना चाहते हैं, तो मुझे विश्वास है कि यह उपयोगी है (शीर्षक सभी तालिकाओं को हटाने का स्पष्ट रूप से उल्लेख नहीं करता है)।


0

यदि आप एक mysql सर्वर पर हैं और यदि आपको अपनी तालिकाओं को खोने में कोई आपत्ति नहीं है, तो आप एक सरल क्वेरी का उपयोग कर सकते हैं:

SET foreign_key_checks = 0;
DROP TABLE IF EXISTS table_a,table_b,table_c,table_etc;
SET foreign_key_checks = 1;

इस तरह यह मायने नहीं रखता कि आप किस क्रम में तालिका का उपयोग करते हैं।

यदि कोई इस तथ्य के बारे में कुछ कहने जा रहा है कि यह एक अच्छा समाधान नहीं है यदि आपके पास कई तालिकाओं के साथ डेटाबेस है: मैं सहमत हूं!


मुझे मिलता हैIncorrect syntax near '='. (102) (SQLExecDirectW)
मैट

@ मेट बिट यह अनुमान लगाने के लिए कि आप किस त्रुटि पर = ''।
एल्स डेन आईईपी

3
foreign_key_checksMSSQL सर्वर पर काम नहीं करेगा। मुझे लगता है कि यह एक MySql विशिष्ट चर है।
ooXei1sh

1
@ ooXei1sh नहीं MSSQL पर। यही कारण है कि मैं अपने पोस्ट की शुरुआत में कहता हूं: "यदि आप एक MYSQL सर्वर पर हैं"।
एल्स डेन आईईपी

0

विदेशी कुंजी बाधा नाम पाने के लिए नीचे दिए गए कोड को निष्पादित करें जो आपके ड्रॉप को रोकता है। उदाहरण के लिए, मैं rolesतालिका लेता हूं ।

      SELECT *
      FROM sys.foreign_keys
      WHERE referenced_object_id = object_id('roles');

      SELECT name AS 'Foreign Key Constraint Name',
      OBJECT_SCHEMA_NAME(parent_object_id) + '.' + OBJECT_NAME(parent_object_id)
      AS 'Child Table' FROM sys.foreign_keys
      WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'dbo'
      AND OBJECT_NAME(referenced_object_id) = 'dbo.roles'

आपको FK नाम कुछ इस प्रकार मिलेगा: FK__Table1__roleId__1X1H55C1

अब ऊपर से प्राप्त FK संदर्भ को हटाने के लिए नीचे दिया गया कोड चलाएँ।

ALTER TABLE dbo.users drop CONSTRAINT FK__Table1__roleId__1X1H55C1;

किया हुआ!


-4

अगर मैं अपने डेटाबेस की सभी तालिकाओं को हटाना चाहता हूं

फिर पूरे डेटाबेस को गिराना बहुत आसान है:

DROP DATABASE WorkerPensions

71
आपको इसके लिए एक -1 देना क्योंकि यह प्रश्न का एक वैध उत्तर नहीं है, दो महत्वपूर्ण कारणों से: 1) यह तालिकाओं से बहुत अधिक हटाता है! संग्रहीत कार्यविधियाँ, फ़ंक्शंस, UDTs, सुरक्षा, .NET असेंबली, आदि सभी एक DROP DATABASE के साथ चले जाते हैं। 2) आपको डेटाबेस बनाने की अनुमति नहीं दी जा सकती है, उदाहरण के लिए केंद्रीय रूप से प्रबंधित देव वातावरण, जहां डेटाबेस आईटी द्वारा प्रावधानित हैं और क्रिएट-टाइम पर अतिरिक्त आवश्यकताएं हैं जिनके बारे में आपको जानकारी नहीं है।
वॉरेन रुमक

-4

यदि आप DROPएक मेज चाहते हैं जिसे विदेशी कुंजी का उपयोग करके अन्य तालिका द्वारा संदर्भित किया गया है

DROP TABLE *table_name* CASCADE CONSTRAINTS;
मुझे लगता है कि यह आपके लिए काम करना चाहिए।


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