SQL Drop Table Straint
-
21-09-2019 - |
سؤال
إذا كنت أرغب في حذف جميع الجداول في قاعدة البيانات الخاصة بي مثل هذا ، فهل ستهتم بالقيود الرئيسية الخارجية؟ إذا لم يكن كذلك ، كيف أعتني بذلك أولاً؟
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;
أعتقد أنه ينبغي أن يعمل من أجلك.