INFORMATION_SCHEMA를 사용하여 기본 제약 조건을 어떻게 찾습니까?


116

주어진 기본 제약 조건이 존재하는지 테스트하려고합니다. sysobjects 테이블을 사용하고 싶지 않지만보다 표준적인 INFORMATION_SCHEMA를 사용합니다.

이전에 테이블 및 기본 키 제약 조건을 확인하는 데 사용했지만 기본 제약 조건이 어디에도 표시되지 않습니다.

거기에 없나요? (저는 MS SQL Server 2000을 사용하고 있습니다).

편집 : 제약의 이름을 찾고 있어요.

답변:


121

내가 이해하는대로 기본값 제약 조건은 ISO 표준의 일부가 아니므로 INFORMATION_SCHEMA에 나타나지 않습니다. INFORMATION_SCHEMA는 크로스 플랫폼이기 때문에 이러한 종류의 작업에 가장 적합한 선택처럼 보이지만 정보를 사용할 수없는 경우 SQL Server에서 더 이상 사용되지 않는 시스템 테이블 뷰 대신 개체 카탈로그 뷰 (sys. *)를 사용해야합니다. 2005 년 이후.

아래는 @ user186476의 답변과 거의 같습니다. 주어진 열에 대한 기본값 제약 조건의 이름을 반환합니다. (SQL Server가 아닌 사용자의 경우이를 삭제하려면 기본값의 이름이 필요합니다. 기본 제약 조건의 이름을 직접 지정하지 않으면 SQL Server는 "DF_TableN_Colum_95AFE4B5"와 같은 이상한 이름을 만듭니다. 쉽게 변경할 수 있도록하기 위해 스키마는 항상 명시 적으로 제약 조건을 지정하십시오!)

-- returns name of a column's default value constraint 
SELECT
    default_constraints.name
FROM 
    sys.all_columns

        INNER JOIN
    sys.tables
        ON all_columns.object_id = tables.object_id

        INNER JOIN 
    sys.schemas
        ON tables.schema_id = schemas.schema_id

        INNER JOIN
    sys.default_constraints
        ON all_columns.default_object_id = default_constraints.object_id

WHERE 
        schemas.name = 'dbo'
    AND tables.name = 'tablename'
    AND all_columns.name = 'columnname'

1
참고 : 다른 스키마에서 동일한 테이블 이름을 가질 수 있으므로 sys.schemas 테이블에서도 조인해야합니다.
Daniel James Bryars 2012 년

1
@DanielJamesBryars sys.schemas가 이제 쿼리에 추가되었습니다.
Stephen Turner

짧고 달콤하고 모든 버전의 SQL Server에서 작동하며 테이블 이 없으며 기억하기 쉬운 내 대답 을 참조하십시오 sys.
ErikE 2015 년

2
@ErikE 코드는 기본 제약 조건의 이름을 알고 있다고 가정합니다. 코드에서 알 수 있듯이 해결하기 쉬운 문제입니다. 좋은 대답, 틀린 질문.
DarLom 2015 년

내 코드는 질문자가 요청한 것이기 때문에 "제약 조건의 이름으로 [ '주어진 기본 제약 조건이 존재하는지']를 찾고 있습니다."라고 가정합니다. 나는 직접 질문을 만족시키는 성격을 훨씬 더 명확하게 만들기 위해 내 대답을 편집했습니다. 도움이되기를 바랍니다.
ErikE 2015 년

43

다음을 사용하여 기본 제약 조건이 상호 관련된 테이블 이름 및 열 이름을 지정하여 결과를 더욱 좁힐 수 있습니다.

select * from sysobjects o 
inner join syscolumns c
on o.id = c.cdefault
inner join sysobjects t
on c.id = t.id
where o.xtype = 'D'
and c.name = 'Column_Name'
and t.name = 'Table_Name'

1
몇 시간 동안이 간단한 쿼리를 검색합니다. Thannnnnkkk youuuu!
Samuel

작동하려면 o.xtype = 'D'가 있어야합니다. 대소 문자를 구분하지 않는 데이터베이스입니다.
IvanH

37

기본 제약 조건 이름이없는 것 같습니다. Information_Schema보기 .

SELECT * FROM sysobjects WHERE xtype = 'D' AND name = @name 이름으로 기본 제약 조건을 찾는 데 사용


내가 필요한 것만. 감사합니다
drdwilcox 2013 년

나중 대안 (SQL 2000 및 제약 이름 별 쿼리)보다 질문에 직접 응답합니다.
Marc L.

이것은 제약 이름을 알고있을 때만 작동하지만 이것이 시스템이 할당 된 경우에만 작동합니다 ....
TS

12

아래 스크립트는 실행중인 데이터베이스의 사용자 테이블에 대한 모든 기본 제약 조건과 기본값을 나열합니다.

SELECT  
        b.name AS TABLE_NAME,
        d.name AS COLUMN_NAME,
        a.name AS CONSTRAINT_NAME,
        c.text AS DEFAULT_VALUE
FROM sys.sysobjects a INNER JOIN
        (SELECT name, id
         FROM sys.sysobjects 
         WHERE xtype = 'U') b on (a.parent_obj = b.id)
                      INNER JOIN sys.syscomments c ON (a.id = c.id)
                      INNER JOIN sys.syscolumns d ON (d.cdefault = a.id)                                          
 WHERE a.xtype = 'D'        
 ORDER BY b.name, a.name

5

열 또는 테이블 이름으로 제약 조건을 얻거나 데이터베이스의 모든 제약 조건을 얻으려면 다른 답변을 찾으십시오. 그러나 질문이 정확히 무엇을 요구하는지, 즉 "주어진 기본 제약 조건이 존재하는지 ... 제약 이름으로 테스트" 하는 것을 찾고 있다면 훨씬 더 쉬운 방법이 있습니다.

다음은 sysobjects또는 다른 sys테이블을 전혀 사용하지 않는 미래 보장형 답변입니다 .

IF object_id('DF_CONSTRAINT_NAME', 'D') IS NOT NULL BEGIN
   -- constraint exists, work with it.
END

3
select c.name, col.name from sys.default_constraints c
    inner join sys.columns col on col.default_object_id = c.object_id
    inner join sys.objects o  on o.object_id = c.parent_object_id
    inner join sys.schemas s on s.schema_id = o.schema_id
where s.name = @SchemaName and o.name = @TableName and col.name = @ColumnName

1
공백이 조금 더 있으면 좋겠지 만 원래 포스터가 이전 버전과의 호환성 시스템 테이블보기보다 Microsoft에서 권장하는 개체 카탈로그보기 (sys. *)를 사용하여 요청한대로 수행됩니다.
로버트 칼혼

2

INFORMATION_SCHEMA.COLUMNS의 COLUMN_DEFAULT 열이 찾고있는 것입니까?


예, 아니오, 기본값이 있고 그것이 무엇인지 알려주지 만 제약 조건의 이름도 필요합니다.
WildJoe

1
또한 런타임 SQL 로그인이 dbo 스키마를 소유하지 않은 경우 COLUMN_DEFAULT 열에서 NULL 값만 찾을 수 있습니다.
Glen Little

1
WHILE EXISTS( 
    SELECT * FROM  sys.all_columns 
    INNER JOIN sys.tables ST  ON all_columns.object_id = ST.object_id
    INNER JOIN sys.schemas ON ST.schema_id = schemas.schema_id
    INNER JOIN sys.default_constraints ON all_columns.default_object_id = default_constraints.object_id
    WHERE 
    schemas.name = 'dbo'
    AND ST.name = 'MyTable'
)
BEGIN 
DECLARE @SQL NVARCHAR(MAX) = N'';

SET @SQL = (  SELECT TOP 1
     'ALTER TABLE ['+  schemas.name + '].[' + ST.name + '] DROP CONSTRAINT ' + default_constraints.name + ';'
   FROM 
      sys.all_columns

         INNER JOIN
      sys.tables ST
         ON all_columns.object_id = ST.object_id

         INNER JOIN 
      sys.schemas
         ON ST.schema_id = schemas.schema_id

         INNER JOIN
      sys.default_constraints
         ON all_columns.default_object_id = default_constraints.object_id

   WHERE 
         schemas.name = 'dbo'
      AND ST.name = 'MyTable'
      )
   PRINT @SQL
   EXECUTE sp_executesql @SQL 

   --End if Error 
   IF @@ERROR <> 0 
   BREAK
END 

1

네크 로맨싱.
default-constraint가 존재하는지 만 확인해야하는 경우
(default-constraint (s)가 제대로 관리되지 않는 DB에서 다른 이름을 가질 수 있음),
INFORMATION_SCHEMA.COLUMNS (column_default)를 사용합니다.

IF NOT EXISTS(
    SELECT * FROM INFORMATION_SCHEMA.COLUMNS
    WHERE (1=1) 
    AND TABLE_SCHEMA = 'dbo' 
    AND TABLE_NAME = 'T_VWS_PdfBibliothek' 
    AND COLUMN_NAME = 'PB_Text'
    AND COLUMN_DEFAULT IS NOT NULL  
)
BEGIN 
    EXECUTE('ALTER TABLE dbo.T_VWS_PdfBibliothek 
                ADD CONSTRAINT DF_T_VWS_PdfBibliothek_PB_Text DEFAULT (N''image'') FOR PB_Text; 
    '); 
END 

제약 이름으로 만 확인하려는 경우 :

-- Alternative way: 
IF OBJECT_ID('DF_CONSTRAINT_NAME', 'D') IS NOT NULL 
BEGIN
    -- constraint exists, deal with it.
END 

마지막으로,
INFORMATION_SCHEMA.DEFAULT_CONSTRAINTS 라는 뷰를 만들 수 있습니다 .

CREATE VIEW INFORMATION_SCHEMA.DEFAULT_CONSTRAINTS 
AS 
SELECT 
     DB_NAME() AS CONSTRAINT_CATALOG 
    ,csch.name AS CONSTRAINT_SCHEMA
    ,dc.name AS CONSTRAINT_NAME 
    ,DB_NAME() AS TABLE_CATALOG 
    ,sch.name AS TABLE_SCHEMA 
    ,syst.name AS TABLE_NAME 
    ,sysc.name AS COLUMN_NAME 
    ,COLUMNPROPERTY(sysc.object_id, sysc.name, 'ordinal') AS ORDINAL_POSITION 
    ,dc.type_desc AS CONSTRAINT_TYPE 
    ,dc.definition AS COLUMN_DEFAULT 

    -- ,dc.create_date 
    -- ,dc.modify_date 
FROM sys.columns AS sysc -- 46918 / 3892 with inner joins + where 
-- FROM sys.all_columns AS sysc -- 55429 / 3892 with inner joins + where 

INNER JOIN sys.tables AS syst 
    ON syst.object_id = sysc.object_id 

INNER JOIN sys.schemas AS sch
    ON sch.schema_id = syst.schema_id 

INNER JOIN sys.default_constraints AS dc 
    ON sysc.default_object_id = dc.object_id

INNER JOIN sys.schemas AS csch
    ON csch.schema_id = dc.schema_id 

WHERE (1=1) 
AND dc.is_ms_shipped = 0 

/*
WHERE (1=1) 
AND sch.name = 'dbo'
AND syst.name = 'tablename'
AND sysc.name = 'columnname'
*/

0

나는 그것이 INFORMATION_SCHEMA에 있다고 생각하지 않습니다-아마도 sysobjects 또는 관련 더 이상 사용되지 않는 테이블 / 뷰를 사용해야 할 것입니다.

INFORMATION_SCHEMA.TABLE_CONSTRAINTS에 이에 대한 유형이 있다고 생각할 수 있지만 보이지 않습니다.


0

아마도 다른 SQL DBMS 중 일부에서는 "기본 제약 조건"이 실제로 제약 조건이 아니기 때문에 "INFORMATION_SCHEMA.TABLE_CONSTRAINTS"에서 이름을 찾을 수 없으므로 다른 사람들이 이미 언급했듯이 "INFORMATION_SCHEMA.COLUMNS"가 가장 좋습니다.

(여기에 SQLServer-ignoramus)

"기본 제약 조건"의 이름을 알아야 할 때 제가 생각할 수있는 유일한 이유는 SQLServer가 "ALTER TABLE xxx ALTER COLUMN yyy SET DEFAULT..."명령을 지원하지 않는 경우 입니다. 그러나 이미 비표준 영역에 있으며 필요한 것을 얻기 위해 제품 별 방법을 사용해야합니다.


0

CHECK_CONSTRAINTS와 CONSTRAINT_COLUMN_USAGE의 조합을 사용하는 방법 :

    select columns.table_name,columns.column_name,columns.column_default,checks.constraint_name
          from information_schema.columns columns
             inner join information_schema.constraint_column_usage usage on 
                  columns.column_name = usage.column_name and columns.table_name = usage.table_name
             inner join information_schema.check_constraints checks on usage.constraint_name = checks.constraint_name
    where columns.column_default is not null

CONSTRAINT_COLUMN_USAGE에는 기본 제약 조건에 대한 정보가 없습니다.
Stephen Turner

0

다음 스크립트를 사용하여 모든 기본값 (sp_binddefaults) 및 모든 기본 제약 조건을 검색하기 위해 다음 스크립트를 사용하고 있습니다.

SELECT 
    t.name AS TableName, c.name AS ColumnName, SC.COLUMN_DEFAULT AS DefaultValue, dc.name AS DefaultConstraintName
FROM  
    sys.all_columns c
    JOIN sys.tables t ON c.object_id = t.object_id
    JOIN sys.schemas s ON t.schema_id = s.schema_id
    LEFT JOIN sys.default_constraints dc ON c.default_object_id = dc.object_id
    LEFT JOIN INFORMATION_SCHEMA.COLUMNS SC ON (SC.TABLE_NAME = t.name AND SC.COLUMN_NAME = c.name)
WHERE 
    SC.COLUMN_DEFAULT IS NOT NULL
    --WHERE t.name = '' and c.name = ''

0

개체 카탈로그보기 : sys.default_constraints

정보 스키마 뷰 INFORMATION_SCHEMA는 ANSI 규격이지만 기본 제약 조건은 ISO 표준의 일부가 아닙니다. Microsoft SQL Server는 SQL Server 개체 메타 데이터에 대한 정보를 얻기위한 시스템 카탈로그보기를 제공합니다.

sys.default_constraints 기본 제약 조건에 대한 정보를 가져 오는 데 사용되는 시스템 카탈로그 뷰입니다.

SELECT so.object_id TableName,
       ss.name AS TableSchema,
       cc.name AS Name,
       cc.object_id AS ObjectID,              
       sc.name AS ColumnName,
       cc.parent_column_id AS ColumnID,
       cc.definition AS Defination,
       CONVERT(BIT,
               CASE cc.is_system_named
                   WHEN 1
                   THEN 1
                   ELSE 0
               END) AS IsSystemNamed,
       cc.create_date AS CreationDate,
       cc.modify_date AS LastModifiednDate
FROM sys.default_constraints cc WITH (NOLOCK)
     INNER JOIN sys.objects so WITH (NOLOCK) ON so.object_id = cc.parent_object_id
     LEFT JOIN sys.schemas ss WITH (NOLOCK) ON ss.schema_id = so.schema_id
     LEFT JOIN sys.columns sc WITH (NOLOCK) ON sc.column_id = cc.parent_column_id
                                               AND sc.object_id = cc.parent_object_id
ORDER BY so.name,
         cc.name;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.