سؤال

إذا كنت أرغب في حذف جميع الجداول في قاعدة البيانات الخاصة بي مثل هذا ، فهل ستهتم بالقيود الرئيسية الخارجية؟ إذا لم يكن كذلك ، كيف أعتني بذلك أولاً؟

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]
هل كانت مفيدة؟

المحلول

لا ، هذا لن يسقط طاولتك إذا كانت هناك بالفعل مفاتيح أجنبية تشير إليها.

للحصول على جميع العلاقات الرئيسية الخارجية التي تشير إلى جدولك ، يمكنك استخدام SQL هذا (إذا كنت على SQL Server 2005 وما فوق):

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

وإذا كان هناك أي ، مع هذا البيان هنا ، يمكنك إنشاء عبارات SQL لإسقاط علاقات FK هذه بالفعل:

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')

نصائح أخرى

في SQL Server Management Studio 2008 (R2) وأحدث ، يمكنك النقر بزر الماوس الأيمن على

DB -> المهام -> إنشاء البرامج النصية

  • حدد الجداول التي تريد إسقاطها.

  • حدد "حفظ إلى نافذة الاستعلام الجديدة".

  • انقر على الزر المتقدم.

  • اضبط Script Drop و Create to Script Drop.

  • تعيين مفاتيح أجنبية نصية على صحيح.

  • انقر فوق موافق.

  • انقر فوق التالي -> التالي -> الانتهاء.

  • عرض البرنامج النصي ثم تنفذ.

إذا قمت بإسقاط جدول "الطفل" أولاً ، فسيتم إسقاط المفتاح الخارجي أيضًا. إذا حاولت إسقاط جدول "الوالد" أولاً ، فستحصل على "لا يمكن إسقاط كائن" أ "لأنه يشير إليه من خلال قيود مفتاح خارجي". خطأ.

إليك طريقة أخرى لإسقاط جميع الجداول بشكل صحيح ، باستخدام sp_MSdropconstraints إجراء. أقصر رمز يمكن أن أفكر فيه:

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

إذا كان SQL Server ، فيجب عليك إسقاط القيد قبل أن تتمكن من إسقاط الجدول.

نسخة أكثر عاما قليلا مما نشر

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')

فقط قم بتوصيل اسم الجدول الخاص بك ، وتنفيذ نتيجة ذلك.

إليك طريقة أخرى لحذف جميع القيود التي تليها الجداول نفسها ، باستخدام خدعة متسلسلة تتضمن 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)

فيما يلي برنامج نصي كامل لتنفيذ حل:

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
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.

باستخدام SQL Server Manager ، يمكنك إسقاط قيود المفاتيح الخارجية من واجهة المستخدم. إذا كنت تريد حذف الجدول Diary لكن جدول المستخدم لديه مفتاح خارجي DiaryId مشيرا إلى Diary الجدول ، يمكنك توسيع (باستخدام رمز Plus) User الجدول ثم قم بتوسيع ملف Foreign Keys الجزء. انقر بزر الماوس الأيمن على المفتاح الخارجي الذي يشير إلى جدول اليوميات ثم حدد Delete. يمكنك بعد ذلك توسيع ملف Columns القسم ، انقر بزر الماوس الأيمن وحذف العمود DiaryId جدا. ثم يمكنك فقط الجري:

drop table Diary

أعلم أن سؤالك الفعلي يدور حول حذف جميع الجداول ، لذلك قد لا يكون هذا مفيدًا لهذه الحالة. ومع ذلك ، إذا كنت ترغب فقط في حذف بعض الجداول ، فهذا مفيد أعتقد (العنوان لا يذكر صراحة حذف جميع الجداول).

إذا كنت على خادم MySQL وإذا كنت لا تمانع في فقدان الجداول الخاصة بك ، فيمكنك استخدام استعلام بسيط لحذف جداول متعددة في وقت واحد:

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

وبهذه الطريقة لا يهم أي ترتيب تستخدم الجدول في الاستعلام.

إذا كان أي شخص سيقول شيئًا عن حقيقة أن هذا ليس حلاً جيدًا إذا كان لديك قاعدة بيانات بها العديد من الجداول: أوافق!

إذا أردت حذف جميع الجداول في قاعدة البيانات الخاصة بي

ثم من الأسهل بكثير إسقاط قاعدة البيانات بأكملها:

DROP DATABASE WorkerPensions

إذا أردت أن DROP جدول تمت الإشارة إليه بواسطة جدول آخر باستخدام استخدام المفتاح الخارجي

DROP TABLE *table_name* CASCADE CONSTRAINTS;
أعتقد أنه ينبغي أن يعمل من أجلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top