Как отбросить список таблиц SQL Server, игнорируя ограничения? - PullRequest
13 голосов
/ 12 ноября 2009

У меня есть список из полдюжины таблиц MSSQL 2008, которые я хотел бы сразу удалить из своей базы данных. Данные были полностью перенесены в новые таблицы. В таблицах new нет ссылок на таблицы old .

Проблема в том, что старые таблицы содержат множество внутренних ограничений FK, которые были автоматически сгенерированы инструментом (на самом деле aspnet_regsql). Следовательно, сбросить все ограничения вручную - настоящая боль.

Как я могу удалить старые таблицы, игнорируя все внутренние ограничения?

Ответы [ 6 ]

6 голосов
/ 17 января 2013

Это зависит от того, как вы хотите сбросить таблицы. Если список таблиц нужно закрыть почти на 20% таблиц под вашей БД.

Затем я отключу все ограничения в этой БД под моим сценарием, исключу таблицы и включу ограничения для того же сценария.

--To Disable a Constraint at DB level

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'

--Write the code to DROP tables

DROP TABLE TABLENAME

DROP TABLE TABLENAME

DROP TABLE TABLENAME

--To Enable a Constraint at DB level

EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'

Наконец, чтобы проверить статус ваших ограничений, запустите этот запрос.

--Checks the Status of Constraints

SELECT (CASE 
    WHEN OBJECTPROPERTY(CONSTID, 'CNSTISDISABLED') = 0 THEN 'ENABLED'
    ELSE 'DISABLED'
    END) AS STATUS,
    OBJECT_NAME(CONSTID) AS CONSTRAINT_NAME,
    OBJECT_NAME(FKEYID) AS TABLE_NAME,
    COL_NAME(FKEYID, FKEY) AS COLUMN_NAME,
    OBJECT_NAME(RKEYID) AS REFERENCED_TABLE_NAME,
    COL_NAME(RKEYID, RKEY) AS REFERENCED_COLUMN_NAME
FROM SYSFOREIGNKEYS
ORDER BY TABLE_NAME, CONSTRAINT_NAME,REFERENCED_TABLE_NAME, KEYNO

Если вы не хотите отключать ограничения на уровне базы данных, составьте список таблиц, которые вы хотите удалить.

Шаг 1: Проверьте ограничения, связанные с этими таблицами

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

Шаг 2: отключить ограничения, связанные с этими таблицами.

ALTER TABLE MyTable NOCHECK CONSTRAINT MyConstraint

Шаг 3: Бросить столы

DROP TABLE TABLENAME
3 голосов
/ 12 ноября 2009

Простое DROP TABLE dbo.MyTable будет игнорировать все ограничения (и триггеры), кроме внешних ключей (если вы сначала не удалите дочернюю / ссылочную таблицу), где вам, возможно, придется сначала их удалить.

Редактировать: после комментария:

Автоматического пути нет. Вам нужно будет перебрать sys.foreign_keys и сгенерировать несколько операторов ALTER TABLE.

2 голосов
/ 25 мая 2017

Запустите следующий скрипт, чтобы удалить все ограничения во всех таблицах в текущей БД, а затем запустите операторы отбрасывания таблиц.

DECLARE @dropAllConstraints NVARCHAR(MAX) = N'';

SELECT @dropAllConstraints  += N'
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id))
    + '.' + QUOTENAME(OBJECT_NAME(parent_object_id)) + 
    ' DROP CONSTRAINT ' + QUOTENAME(name) + ';'
FROM sys.foreign_keys;
EXEC sp_executesql @dropAllConstraints 
1 голос
/ 28 ноября 2012

Я нашел разумный (ish) способ сделать это, заставив SQL написать SQL, чтобы снять ограничения:

select concat("alter table ", table_name, " drop ", constraint_type ," ", constraint_name, ";")
  from information_schema.table_constraints 
  where table_name like 'somefoo_%' 
        and 
        constraint_type <> "PRIMARY KEY";

Вы можете изменить имя таблицы в соответствии с вашими потребностями или, возможно, выбрать другой столбец / значения.

Кроме того, это выберет любое ограничение не первичного ключа, которое может быть слишком большим для кувалды. Может быть, вам нужно просто установить =?

Я не администратор базы данных. возможно, есть лучшие способы сделать это, но для моих целей это сработало достаточно.

0 голосов
/ 12 ноября 2009

Я наконец-то нашел решение на основе сценария , предоставленного Джейсоном Пресли . Этот скрипт автоматически удаляет все ограничения в БД. Предложение WHERE легко добавить, чтобы оно применялось только к набору соответствующих таблиц. После этого отбросить все столы просто.

0 голосов
/ 12 ноября 2009

Я подозреваю, что перед удалением нужно выполнить команду 'изменить' в таблицах, которые нарушают работу, чтобы устранить несоответствия между чужими ключами.

ALTER TABLE Orders DROP FOREIGN KEY fk_PerOrders;
DROP TABLE Orders;

Конечно, если вы сначала отбросите дочерние таблицы, то у вас не возникнет этой проблемы. (если у вас нет ограничений таблицы A на таблицу B и ограничения таблицы B на A, вам потребуется изменить одну из таблиц, например, A, чтобы удалить ограничение)

например. это НЕ БУДЕТ работать, так как Orders имеет ограничение от Order_Lines

DROP TABLE Orders;
DROP TABLE Order_lines;

например. это будет работать

DROP TABLE Order_lines;
DROP TABLE Orders;
...