이름을 몰라도 SQL 기본 제약 조건을 삭제하는 방법은 무엇입니까?


196

Microsoft SQL Server에서 열에 대한 기본 제약 조건이 있는지 확인하고 기본 제약 조건을 삭제하는 쿼리는 다음과 같습니다.

IF EXISTS(SELECT * FROM sysconstraints
  WHERE id=OBJECT_ID('SomeTable')
  AND COL_NAME(id,colid)='ColName'
  AND OBJECTPROPERTY(constid, 'IsDefaultCnst')=1)    
ALTER TABLE SomeTable DROP CONSTRAINT DF_SomeTable_ColName

그러나 이전 버전의 데이터베이스에는 오타가 있으므로 제약 조건의 이름은 DF_SomeTable_ColName또는 일 수 있습니다 DF_SmoeTable_ColName.

SQL 오류없이 기본 제약 조건을 어떻게 삭제합니까? INFORMATION_SCHEMA 테이블에는 기본 제약 조건 이름이 표시되지 않으므로 조금 까다로워집니다.

따라서 '이 테이블 / 열의 기본 제약 조건 삭제 DF_SmoeTable_ColName' 또는 '삭제 '와 같은 것이지만 찾을 수 없으면 오류가 발생하지 않습니다.


1
SQL Server에 능숙하지 않습니다. 이름을 찾은 후 제약 조건의 이름을 바꿀 수 있습니까? Oracle에서 "테이블 이름 변경 제약 조건 xxx를 yyy로 변경"
Juergen Hartelt

답변:


262

다음 스크립트는 Mitch Wheat의 코드를 확장하여 구속 조건을 삭제하고 동적으로 실행하는 명령을 생성합니다.

declare @schema_name nvarchar(256)
declare @table_name nvarchar(256)
declare @col_name nvarchar(256)
declare @Command  nvarchar(1000)

set @schema_name = N'MySchema'
set @table_name = N'Department'
set @col_name = N'ModifiedDate'

select @Command = 'ALTER TABLE ' + @schema_name + '.[' + @table_name + '] DROP CONSTRAINT ' + d.name
 from sys.tables t
  join sys.default_constraints d on d.parent_object_id = t.object_id
  join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id
 where t.name = @table_name
  and t.schema_id = schema_id(@schema_name)
  and c.name = @col_name

--print @Command

execute (@Command)

1
stackoverflow.com/a/15786313/2049986 에서 테이블에 대한 모든 제약 조건을 제거하는 버전을 확인 하십시오.
Jacob van Lingen

sys.default_constraints가 아닌 sys.check_constraints를 사용합니다
Kiquenet

여러 개의 기본 제약 조건 또는 검사 제약 조건 이있는 일부 열이생성 된경우 유효하지 않으며 쿼리의 마지막 제약 조건 에대해서만 실행됩니다.
Kiquenet

4
이 쿼리는 기본 제약 조건 만 해결하며, 열당 하나만있을 수 있습니다. 점검 제한 조건 처리는 다른 문제점입니다.
Philip Kelley

1
기본이 아닌 스키마 이름에 대한 지원을 추가하기 위해이 답변을 업데이트했습니다. 마음에 들지 않기를 바랍니다. 원한다면 별도의 답변을 되돌릴 수 있습니다.
Jakub Januszkiewicz

234

Rob Farley의 블로그 게시물이 도움이 될 수 있습니다.

다음과 같은 것 :

 declare @table_name nvarchar(256)
 declare @col_name nvarchar(256)
 set @table_name = N'Department'
 set @col_name = N'ModifiedDate'

 select t.name, c.name, d.name, d.definition
 from 
     sys.tables t
     join sys.default_constraints d on d.parent_object_id = t.object_id
     join sys.columns c on c.object_id = t.object_id
                           and c.column_id = d.parent_column_id
 where 
     t.name = @table_name
     and c.name = @col_name

104

나는 이것이 작동하고 조인을 사용하지 않는다는 것을 발견했다.

DECLARE @ObjectName NVARCHAR(100)
SELECT @ObjectName = OBJECT_NAME([default_object_id]) FROM SYS.COLUMNS
WHERE [object_id] = OBJECT_ID('[tableSchema].[tableName]') AND [name] = 'columnName';
EXEC('ALTER TABLE [tableSchema].[tableName] DROP CONSTRAINT ' + @ObjectName)

쿼리에서 정확히 일치하는 항목을 찾고 [columnName] 인 경우 아무 것도 반환하지 않으므로 columnName에 대괄호가 없는지 확인하십시오.


1
이 답변은 다른 답변과 달리 기본 [dbo] 이외의 스키마에서 작동합니다.
Contango

테스트하지는 않았지만 주변에 WHILE (@ObjectName IS NULL이 아님)을 추가하고 SELECT (at) ObjectName = OBJECT_Name ([default ...) 앞에 TOP 1을 넣고 EXEC ( 'ALTER 만 실행) TA ... (at) ObjectName이 NULL이 아닌 경우
ScubaSteve

6
이 스크립트를 dem 등원으로 만들려면 IF @ObjectName IS NOT NULLEXEC 명령
7

3
CHECK 제약 조건을 사용하여 나를 위해 작동하지 않습니다 . [default_object_id])이다 . NULL 값을 얻습니다 .
Kiquenet

달콤하고 단순하지만 Microsoft 문서에 따르면 이러한 일을하는 방식은 영원히 지속되지는 않습니다. 다음 버전 docs.microsoft.com/en-us/sql/t-sql/statements/…
Hopeless

11

여러 열에 대한 제약 조건을 삭제하려면

declare @table_name nvarchar(256)

declare @Command nvarchar(max) = ''

set @table_name = N'ATableName'

select @Command = @Command + 'ALTER TABLE ' + @table_name + ' drop constraint ' + d.name + CHAR(10)+ CHAR(13)
from sys.tables t
join sys.default_constraints d on d.parent_object_id = t.object_id
join sys.columns c on c.object_id = t.object_id
     and c.column_id = d.parent_column_id
where t.name = @table_name and c.name in ('column1','column2','column3')

--print @Command

execute (@Command)

5

확장 된 솔루션 (테이블 스키마 고려) :

-- Drop default contstraint for SchemaName.TableName.ColumnName
DECLARE @schema_name NVARCHAR(256)
DECLARE @table_name NVARCHAR(256)
DECLARE @col_name NVARCHAR(256)
DECLARE @Command  NVARCHAR(1000)

set @schema_name = N'SchemaName'
set @table_name = N'TableName'
set @col_name = N'ColumnName'

SELECT @Command = 'ALTER TABLE [' + @schema_name + '].[' + @table_name + '] DROP CONSTRAINT ' + d.name
 FROM sys.tables t   
  JOIN sys.default_constraints d       
   ON d.parent_object_id = t.object_id  
  JOIN sys.schemas s
        ON s.schema_id = t.schema_id
  JOIN    sys.columns c      
   ON c.object_id = t.object_id      
    AND c.column_id = d.parent_column_id
 WHERE t.name = @table_name
    AND s.name = @schema_name 
  AND c.name = @col_name

EXECUTE (@Command)

3

nvarchar (max) 임계 값에 대해 안전한 데이터베이스의 모든 기본 제약 조건을 삭제하십시오.

/* WARNING: THE SAMPLE BELOW; DROPS ALL THE DEFAULT CONSTRAINTS IN A DATABASE */ 
/* MAY 03, 2013 - BY WISEROOT  */
declare @table_name nvarchar(128)
declare @column_name nvarchar(128)
declare @df_name nvarchar(128)
declare @cmd nvarchar(128) 

declare table_names cursor for 
 SELECT t.name TableName, c.name ColumnName
 FROM sys.columns c INNER JOIN
     sys.tables t ON c.object_id = t.object_id INNER JOIN
     sys.schemas s ON t.schema_id = s.schema_id
     ORDER BY T.name, c.name

     open table_names
fetch next from table_names into @table_name , @column_name
while @@fetch_status = 0
BEGIN

if exists (SELECT top(1) d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = @table_name and c.name = @column_name)
BEGIN
    SET @df_name = (SELECT top(1) d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = @table_name and c.name = @column_name)
    select @cmd = 'ALTER TABLE [' + @table_name +  '] DROP CONSTRAINT [' +  @df_name + ']'
    print @cmd
    EXEC sp_executeSQL @cmd;
END

  fetch next from table_names into @table_name , @column_name
END

close table_names 
deallocate table_names

여러 개의 기본 제약 조건 또는 검사 제약 조건 이있는 일부 열이생성 된경우 유효하지 않으며 쿼리의 상위 1 제약 조건 에대해서만 실행됩니다.
Kiquenet

2

모든 구속 조건을 찾아 보려면이 명령을 실행하십시오.

exec sp_helpconstraint 'mytable' --and look under constraint_name. 

다음과 같이 보일 것입니다 : DF__Mytable__Column__[ABC123]. 그런 다음 제약 조건을 삭제하면됩니다.


나를 위해 작동하지 않는 :exec sp_helpconstraint 'Roles2016.UsersCRM'
Kiquenet

간부 sp_helpconstraint 'Roles2016'@Kiquenet은 테이블 이름이어야합니다
구운 Inhalf

외래 키 제약 조건을 보여줍니다. 기본값이 아님 constaint
Morez

2

나는 이것이 비슷한 문제를 가진 사람에게 도움이되기를 바랍니다. 에서 ObjectExplorer창에서 데이터베이스를 선택 => 테이블, => 테이블 => 제약. 고객이 열 작성 시간에 정의 된 경우 열 이름을 포함하여 기본 제한 조건 이름을 볼 수 있습니다. 그런 다음 사용하십시오 :

ALTER TABLE  yourTableName DROP CONSTRAINT DF__YourTa__NewCo__47127295;

(제약 이름은 ​​예일뿐입니다)


2

다음 솔루션은 테이블에서 열의 특정 기본 제약 조건을 삭제합니다.

Declare @Const NVARCHAR(256)

SET @Const = (
              SELECT TOP 1 'ALTER TABLE' + YOUR TABLE NAME +' DROP CONSTRAINT '+name
              FROM Sys.default_constraints A
              JOIN sysconstraints B on A.parent_object_id = B.id
              WHERE id = OBJECT_ID('YOUR TABLE NAME')
              AND COL_NAME(id, colid)='COLUMN NAME'
              AND OBJECTPROPERTY(constid,'IsDefaultCnst')=1
            )
 EXEC (@Const)

0

여러 개의 기본 제약 조건이있는 열이 있으므로 다음 저장 프로 시저를 만듭니다.

CREATE PROCEDURE [dbo].[RemoveDefaultConstraints] @table_name nvarchar(256), @column_name nvarchar(256)
AS
BEGIN

    DECLARE @ObjectName NVARCHAR(100)

    START: --Start of loop
    SELECT 
        @ObjectName = OBJECT_NAME([default_object_id]) 
    FROM 
        SYS.COLUMNS
    WHERE 
        [object_id] = OBJECT_ID(@table_name) 
        AND [name] = @column_name;

    -- Don't drop the constraint unless it exists
    IF @ObjectName IS NOT NULL
    BEGIN
        EXEC ('ALTER TABLE '+@table_name+' DROP CONSTRAINT ' + @ObjectName)
        GOTO START; --Used to loop in case of multiple default constraints
    END
END
GO

-- How to run the stored proc.  This removes the default constraint(s) for the enabled column on the User table.
EXEC [dbo].[RemoveDefaultConstraints] N'[dbo].[User]', N'enabled'
GO

-- If you hate the proc, just get rid of it
DROP PROCEDURE [dbo].[RemoveDefaultConstraints]
GO

0

여러 항목을 default constraints or check constraints 만든 일부 열에 유용합니다 .

수정 된 https://stackoverflow.com/a/16359095/206730 스크립트

참고 :이 스크립트는 sys.check_constraints 용입니다.

declare @table_name nvarchar(128)
declare @column_name nvarchar(128)
declare @constraint_name nvarchar(128)
declare @constraint_definition nvarchar(512)

declare @df_name nvarchar(128)
declare @cmd nvarchar(128) 

PRINT 'DROP CONSTRAINT [Roles2016.UsersCRM].Estado'

declare constraints cursor for 
 select t.name TableName, c.name ColumnName, d.name ConstraintName, d.definition ConstraintDefinition
 from sys.tables t   
 join sys.check_constraints d  on d.parent_object_id = t.object_id  
 join sys.columns c  on c.object_id = t.object_id      
 and c.column_id = d.parent_column_id
 where t.name = N'Roles2016.UsersCRM' and c.name = N'Estado'

open constraints
fetch next from constraints into @table_name , @column_name, @constraint_name, @constraint_definition
while @@fetch_status = 0
BEGIN
    print 'CONSTRAINT: ' + @constraint_name
    select @cmd = 'ALTER TABLE [' + @table_name +  '] DROP CONSTRAINT [' +  @constraint_name + ']'
    print @cmd
    EXEC sp_executeSQL @cmd;

  fetch next from constraints into @table_name , @column_name, @constraint_name, @constraint_definition
END

close constraints 
deallocate constraints

0

실행하기 전에 항상 스크립트를 생성하고 검토하십시오. 스크립트 아래

  select 'Alter table dbo.' + t.name + ' drop constraint '+ d.name  
  from sys.tables t
  join sys.default_constraints d on d.parent_object_id = t.object_id
  join sys.columns c on c.object_id = t.object_id
       and c.column_id = d.parent_column_id
  where c.name in ('VersionEffectiveDate','VersionEndDate','VersionReasonDesc')
  order by t.name

0
declare @table_name nvarchar(100)
declare @col_name nvarchar(100)
declare @constraint nvarchar(100)
set @table_name = N'TableName'
set @col_name = N'ColumnName'

IF EXISTS (select       c.*
    from        sys.columns c 
    inner join  sys.tables t on t.object_id = c.object_id
    where       t.name = @table_name
    and         c.name = @col_name) 
BEGIN

select @constraint=d.name
from 
sys.tables t
join sys.default_constraints d on d.parent_object_id = t.object_id
join sys.columns c on c.object_id = t.object_id
and c.column_id = d.parent_column_id
where 
t.name = @table_name
and c.name = @col_name

    IF LEN(ISNULL(@constraint, '')) <> 0
    BEGIN
        DECLARE @sqlcmd VARCHAR(MAX)
        SET @sqlcmd = 'ALTER TABLE ' + QUOTENAME(@table_name) + ' DROP CONSTRAINT' + 
        QUOTENAME(@constraint);
        EXEC (@sqlcmd);

    END

END
GO

0
declare @ery nvarchar(max)
declare @tab nvarchar(max) = 'myTable'
declare @qu nvarchar(max) = 'alter table '+@tab+' drop constraint '

select @ery = (select bj.name from sys.tables as tb 
inner join sys.objects as bj 
on tb.object_id = bj.parent_object_id
where tb.name = @tab and bj.type = 'PK')

exec(@qu+@ery)

구경하다.


2
코드가 솔루션을 제공하더라도 질문을 해결하는 이유에 대해 약간의 설명으로 둘러싼 것이 가장 좋습니다.
Fabien
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.