Удаление неназванных ограничений
Будучи новичком, я создал несколько внешних ключей без явного имени.
Затем я основал SQL сгенерированные сумасшедшие имена, такие как FK__Machines__IdArt__760D22A7
. Угадайте, что они будут сгенерированы с разными именами на разных серверах.
Есть ли какая-нибудь приятная функция, чтобы отказаться от неназванных ограничений FK, передаваемых в качестве аргументов таблиц и соответствующих полей?
Ответы
Ответ 1
Для этого не существует встроенной процедуры, но вы можете создавать свои собственные, используя информацию в представлениях information_schema.
Пример на основе таблицы
Create Proc dropFK(@TableName sysname)
as
Begin
Declare @FK sysname
Declare @SQL nvarchar(4000)
Declare crsFK cursor for
select tu.Constraint_Name from
information_schema.constraint_table_usage TU
LEFT JOIN SYSOBJECTS SO
ON TU.Constraint_NAME = SO.NAME
where xtype = 'F'
and Table_Name = @TableName
open crsFK
fetch next from crsFK into @FK
While (@@Fetch_Status = 0)
Begin
Set @SQL = 'Alter table ' + @TableName + ' Drop Constraint ' + @FK
Print 'Dropping ' + @FK
exec sp_executesql @SQL
fetch next from crsFK into @FK
End
Close crsFK
Deallocate crsFK
End
Ответ 2
Для удаления отдельного неназванного ограничения по умолчанию в столбце используйте следующий код:
DECLARE @ConstraintName VARCHAR(256)
SET @ConstraintName = (
SELECT obj.name
FROM sys.columns col
LEFT OUTER JOIN sys.objects obj
ON obj.object_id = col.default_object_id
AND obj.type = 'F'
WHERE col.object_id = OBJECT_ID('TableName')
AND obj.name IS NOT NULL
AND col.name = 'ColunmName'
)
IF(@ConstraintName IS NOT NULL)
BEGIN
EXEC ('ALTER TABLE [TableName] DROP CONSTRAINT ['[email protected]+']')
END
Если вы хотите сделать это для столбца по умолчанию, который, вероятно, более распространен, чем исходный вопрос, и я уверен, что многие люди приземлится на это из поиска Google, а затем просто измените строку:
obj.type = 'F'
к
obj.type = 'D'
Ответ 3
Это позволит вам отбросить ограничение внешнего ключа на основе имени табуляции + имя столбца
После опроса других ответов у меня просто стояли в системных таблицах, пока я не нашел что-то похожее.
Тот, который вы хотите, это Constraint_Column_Usage, который согласно документам Returns one row for each column in the current database that has a constraint defined on the column.
Я подключил его к sys.objects, чтобы просто получить внешние ключи.
В процедуре (это заимствует из других ответов. cheers guys!):
Create Proc yourSchema.dropFK(@SchemaName NVarChar(128), @TableName NVarChar(128), @ColumnName NVarChar(128))
as
Begin
DECLARE @ConstraintName nvarchar(128)
SET @ConstraintName = (
select c.Constraint_Name
from Information_Schema.Constraint_Column_usage c
left join sys.objects o
on o.name = c.Constraint_Name
where c.TABLE_SCHEMA = @SchemaName and
c.Table_name = @TableName and
c.Column_Name = @ColumnName and
o.type = 'F'
)
exec ('alter table [' + @SchemaName + '].[' + @TableName + '] drop constraint [' + @ConstraintName + ']')
End
Ответ 4
Хотя ответ Gunner ставит людей на правильный путь, если вы хотите отказаться от фактического ограничения DEFAULT, а не ограничения FKey (что и привело меня сюда тоже!), Есть проблемы с ним.
Я думаю, что это исправляет их все. (T-SQL)
CREATE PROC #DropDefaultConstraint @SchemaName sysname, @TableName sysname, @ColumnName sysname
AS
BEGIN
DECLARE @ConstraintName sysname;
SELECT @SchemaName = QUOTENAME(@SchemaName)
, @TableName = QUOTENAME(@TableName);
SELECT @ConstraintName = QUOTENAME(o.name)
FROM sys.columns c
JOIN sys.objects o
ON o.object_id = c.default_object_id
WHERE c.object_id = OBJECT_ID(@SchemaName+'.'[email protected])
AND c.name = @ColumnName;
IF @ConstraintName IS NOT NULL
EXEC ('ALTER TABLE ' + @SchemaName + '.' + @TableName + ' DROP CONSTRAINT ' + @ConstraintName + '');
END