Удаление неназванных ограничений

Будучи новичком, я создал несколько внешних ключей без явного имени.

Затем я основал 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