SQL Server에 제약 조건이 있는지 확인하는 방법은 무엇입니까?


269

나는이 SQL을 가지고있다 :

ALTER TABLE dbo.ChannelPlayerSkins
    DROP CONSTRAINT FK_ChannelPlayerSkins_Channels

그러나 분명히 우리가 사용하는 다른 데이터베이스에서는 제약 조건의 이름이 다릅니다. 이름의 제약이 있는지 어떻게 확인합니까 FK_ChannelPlayerSkins_Channels.



동일한 제약 조건 이름이 여러 개체 또는 다른 스키마에 사용될 때 여기에 나오는 많은 대답이 실패합니다.
Mark Schultheiss

답변:


353

이 시도:

SELECT
    * 
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS 
    WHERE CONSTRAINT_NAME ='FK_ChannelPlayerSkins_Channels'

-- 편집하다 --

원래이 질문에 대답했을 때 원래 질문에서 "FK_ChannelPlayerSkins_Channels"를 찾는 것에 대해 질문했기 때문에 "외국 키"를 생각하고있었습니다. 그 이후로 많은 사람들이 다른 "제약"을 찾는 것에 대해 언급 한 바 있습니다.

--Returns one row for each CHECK, UNIQUE, PRIMARY KEY, and/or FOREIGN KEY
SELECT * 
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    WHERE CONSTRAINT_NAME='XYZ'  


--Returns one row for each FOREIGN KEY constrain
SELECT * 
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS 
    WHERE CONSTRAINT_NAME='XYZ'


--Returns one row for each CHECK constraint 
SELECT * 
    FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS
    WHERE CONSTRAINT_NAME='XYZ'

여기 다른 방법이 있습니다

--Returns 1 row for each CHECK, UNIQUE, PRIMARY KEY, FOREIGN KEY, and/or DEFAULT
SELECT 
    OBJECT_NAME(OBJECT_ID) AS NameofConstraint
        ,SCHEMA_NAME(schema_id) AS SchemaName
        ,OBJECT_NAME(parent_object_id) AS TableName
        ,type_desc AS ConstraintType
    FROM sys.objects
    WHERE type_desc LIKE '%CONSTRAINT'
        AND OBJECT_NAME(OBJECT_ID)='XYZ'

더 많은 제약 정보가 필요한 경우 시스템 저장 프로 시저 내부에서 master.sys.sp_helpconstraint특정 정보를 얻는 방법을 살펴보십시오. SQL Server Management Studio를 사용하여 소스 코드를 보려면 "개체 탐색기"로 이동하십시오. 여기에서 "마스터"데이터베이스를 확장 한 다음 "프로그램 기능", "저장 프로 시저", "시스템 저장 프로 시저"를 차례로 확장하십시오. "sys.sp_helpconstraint"를 찾아 마우스 오른쪽 버튼으로 클릭하고 "modify"를 선택하십시오. 변경 사항을 저장하지 않도록주의하십시오. 또한이 시스템 저장 프로 시저를처럼 사용하여 모든 테이블에서 사용할 수 EXEC sp_helpconstraint YourTableNameHere있습니다.


3
참고로, SQL에서 제약 조건을 추가하기 위해 [fk_Client_ProjectID_Project]와 같이 이름 주위에 대괄호를 사용했습니다. WHERE 절에서 대괄호를 제거해야합니다.
ScubaSteve

2
대괄호에는 문제가 없습니다. 이것은 MySQL 질문이 아니라 SQL Server 질문입니다.
Álvaro González

1
이 고유 제한 조건의 경우는 약간 다른 버전을 필요하지가 존재하는 경우 (INFORMATION_SCHEMA.TABLE_CONSTRAINTS에서 1을 SELECT 곳 CONSTRAINT_NAME = 'UNIQUE_Order_ExternalReferenceId') ALTER TABLE 주문 ADD CONSTRAINT UNIQUE_Order_ExternalReferenceId UNIQUE (ExternalReferenceId) END를 BEGIN
코더

2
위의 항목은 고유 한 열 제약 조건 (SQL2008)에서 작동하지 않았습니다. INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE WHERE CONSTRAINT_NAME = 'UC_constraintName'SELECT * FROM : 나는 다음과 같은 사용했다
앨런 B. 디

기본 제약 조건의 경우 나열된 대체 방법 만 행을 반환합니다.
ChargingPun

247

제약 조건의 존재 여부를 확인하는 가장 쉬운 방법은 OBJECT_ID () 함수를 사용하는 것입니다.

IF OBJECT_ID('dbo.[CK_ConstraintName]', 'C') IS NOT NULL 
    ALTER TABLE dbo.[tablename] DROP CONSTRAINT CK_ConstraintName

OBJECT_ID는 두 번째 매개 변수없이 사용할 수 있으며 (확인 제약 조건의 경우에만 'C') 작동 할 수도 있지만 제약 조건 이름이 데이터베이스의 다른 개체 이름과 일치하면 예기치 않은 결과가 발생할 수 있습니다.

IF OBJECT_ID('dbo.[CK_ConstraintName]') IS NOT NULL 
    ALTER TABLE dbo.[tablename] DROP CONSTRAINT CK_ConstraintName

OBJECT_ID는 외래 키 제약 조건 또는 기본 키 제약 조건 등과 같은 다른 "제약"과 함께 사용할 수도 있습니다. 최상의 결과를 얻으려면 항상 적절한 객체 유형을 OBJECT_ID 함수의 두 번째 매개 변수로 포함하십시오.

구속 조건 객체 유형 :

  • C = 점검 제한 조건
  • D = DEFAULT (제약 또는 독립형)
  • F = 외래 키 제약
  • PK = 기본 키 제약
  • R = 규칙 (구식, 독립형)
  • UQ = 고유 제한

또한 스키마가 종종 필요하다는 점에 유의하십시오. 제약 조건의 스키마는 일반적으로 부모 테이블의 스키마를 사용합니다.

이 방법을 사용할 때 제약 조건 (또는 확인중인 것)을 괄호 안에 넣지 않으면 거짓 부정이 발생할 수 있습니다-객체가.와 같은 이상한 문자를 사용하는 경우 괄호가 필요합니다.


16
중요한 것은 다음과 같이 매개 변수의 스키마 이름을 OBJECT_ID에 추가하는 것입니다. IF OBJECT_ID ( 'dbo.CK_ConstraintName', 'C')는 NULL이 아닙니다. 스키마를 지정하지 않으면 NULL을 반환합니다.
gator88

안녕, 답변 주셔서 감사합니다, 정말 도움이됩니다. 그것이 오라클에 적용되는지 궁금하십니까?
Allen Xia

sql2000에서는 작동하지 않습니다. OBJECTPROPERTY(OBJECT_ID('constraint_name'), 'IsConstraint') = 1현재 버전에서 sql2000까지 호환되도록 사용하십시오 . 어떤 dbo스키마도 필요하지 않습니다.
wqw

47

기본값과 같은 다른 유형의 제약 조건을 찾고 있다면 다른 쿼리를 사용해야합니다 ( INFO_SCHEMA를 사용하여 기본 제약 조건을 어떻게 찾습니까? 에서 devio 응답 ). 사용하다:

SELECT * FROM sys.objects WHERE type = 'D' AND name = @name

이름으로 기본 제약 조건을 찾습니다.

" DDL 'IF not Exists"조건에서 SQL 스크립트를 다시 실행할 수 있도록 다른'IF Not Exists '검사를 조합했습니다. "



19

이 같은 것을보고 있습니까, 아래는 SQL Server 2005에서 테스트되었습니다.

SELECT * FROM sys.check_constraints WHERE 
object_id = OBJECT_ID(N'[dbo].[CK_accounts]') AND 
parent_object_id = OBJECT_ID(N'[dbo]. [accounts]')

10

조심해야 할 것 ......

SQL Server 2008 R2 SSMS에서 "스크립트 제약 조건-> DROP And CREATE To"명령은 아래와 같이 T-SQL을 생성합니다.

USE [MyDatabase]
GO

IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DEF_Detail_IsDeleted]') AND type = 'D')
BEGIN
ALTER TABLE [Patient].[Detail] DROP CONSTRAINT [DEF_Detail_IsDeleted]
END

GO

USE [MyDatabase]
GO

ALTER TABLE [Patient].[Detail] ADD  CONSTRAINT [DEF_Detail_IsDeleted]  DEFAULT ((0)) FOR [IsDeleted]
GO

기본적으로 SELECT는 0 개의 행을 반환하므로이 스크립트는 제약 조건을 삭제하지 않습니다. ( Microsoft Connect 게시 참조 ).

기본 제약 조건의 이름이 잘못되었지만 이름을 변경해도 문제가 해결되지 않기 때문에 OBJECT_ID 함수와 관련이 있습니다.

이 문제를 해결하기 위해 OBJECT_ID 사용법을 제거하고 기본 제약 조건 이름을 대신 사용했습니다.

(SELECT * FROM dbo.sysobjects WHERE [name] = (N'DEF_Detail_IsDeleted') AND type = 'D')

1
스크립트가 이름을 스키마 화하지 않는 것 같습니다. OBJECT_ID(N'[YourSchema].[DEF_Detail_IsDeleted]')다른 스키마에 동일한 이름의 두 제약 조건이있는 경우 사용하는 것이 더 안전 합니다.
Martin Smith

7

기존 쿼리를 만들기 전에 다음 쿼리를 사용하여 기존 제약 조건을 확인합니다.

IF (NOT EXISTS(SELECT 1 FROM sysconstraints WHERE OBJECT_NAME(constid) = 'UX_CONSTRAINT_NAME' AND OBJECT_NAME(id) = 'TABLE_NAME')) BEGIN
...
END

주어진 테이블 이름을 대상으로하는 이름으로 제약 조건을 쿼리합니다. 도움이 되었기를 바랍니다.


3
IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.TableName'))
 BEGIN 
ALTER TABLE TableName DROP CONSTRAINT CONSTRAINTNAME 
END 

3
IF EXISTS(SELECT TOP 1 1 FROM sys.default_constraints WHERE parent_object_id = OBJECT_ID(N'[dbo].[ChannelPlayerSkins]') AND name = 'FK_ChannelPlayerSkins_Channels')
BEGIN
    DROP CONSTRAINT FK_ChannelPlayerSkins_Channels
END
GO

2

INFORMATION_SCHEMA당신의 친구입니다. 모든 종류의 스키마 정보를 표시하는 모든 종류의보기가 있습니다. 시스템 뷰를 확인하십시오. 제약 조건을 다루는 세 가지 뷰가 CHECK_CONSTRAINTS있습니다.


1

나는 이것을 사용하여 열에 대한 원격 제약 조건을 확인합니다. 필요한 모든 것이 있어야합니다.

DECLARE
  @ps_TableName VARCHAR(300)
  , @ps_ColumnName VARCHAR(300)

SET @ps_TableName = 'mytable'
SET @ps_ColumnName = 'mycolumn'

DECLARE c_ConsList CURSOR LOCAL STATIC FORWARD_ONLY FOR
    SELECT
    'ALTER TABLE ' + RTRIM(tb.name) + ' drop constraint ' + sco.name AS csql
    FROM
        sys.Objects tb
        INNER JOIN sys.Columns tc on (tb.Object_id = tc.object_id)
        INNER JOIN sys.sysconstraints sc ON (tc.Object_ID = sc.id and tc.column_id = sc.colid)
        INNER JOIN sys.objects sco ON (sc.Constid = sco.object_id)
    where
        tb.name=@ps_TableName
        AND tc.name=@ps_ColumnName
OPEN c_ConsList
FETCH c_ConsList INTO @ls_SQL
WHILE (@@FETCH_STATUS = 0) BEGIN

    IF RTRIM(ISNULL(@ls_SQL, '')) <> '' BEGIN
        EXECUTE(@ls_SQL)
    END
    FETCH c_ConsList INTO @ls_SQL
END
CLOSE c_ConsList
DEALLOCATE c_ConsList

0
SELECT tabla.name as Tabla,

        restriccion.name as Restriccion, 
        restriccion.type as Tipo, 
        restriccion.type_desc as Tipo_Desc
FROM {DATABASE_NAME}.sys.objects tabla 

INNER JOIN {DATABASE_NAME}.sys.objects restriccion

ON tabla.object_id = restriccion.parent_object_id

WHERE tabla.type = 'U' - Solo tablas creadas por el usuario.

AND restriccion.type = 'UQ' --Tipo de Restriccion UNIQUE

ORDER BY tabla.name, restriccion.type_desc                

1
이 답변은 코드를 덤프하는 것보다 설명이 있으면 더 유용합니다.
Sam Hanley

1
두 번째 @sphanley : 당신은 이미 여러 가지 대답을 얻은 오래된 질문에 대답합니다. 게시 할 가치가 있도록 답변에 대해 더 낫거나 적어도 구체적인 내용을 설명하십시오.
honk

0

하나의 경고와 함께 위의 것을 사용할 수 있습니다.

IF EXISTS(
    SELECT 1 FROM sys.foreign_keys 
    WHERE parent_object_id = OBJECT_ID(N'dbo.TableName') 
        AND name = 'CONSTRAINTNAME'
)
BEGIN 
    ALTER TABLE TableName DROP CONSTRAINT CONSTRAINTNAME 
END 

name = [Constraint name]테이블에 외래 키가 여러 개있을 수 있지만 외래 키를 확인할 필요가 없기 때문에 를 사용해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.