如何使用INFORMATION_SCHEMA查找默认约束?


116

我正在尝试测试是否存在给定的默认约束。我不想使用sysobjects表,而是使用更标准的INFORMATION_SCHEMA。

我以前曾用它来检查表和主键约束,但是在任何地方都看不到默认约束。

他们不在吗?(我正在使用MS SQL Server 2000)。

编辑:我正在寻找通过约束的名称。

Answers:


121

据我了解,默认值约束不是ISO标准的一部分,因此它们不会出现在INFORMATION_SCHEMA中。INFORMATION_SCHEMA似乎是此类任务的最佳选择,因为它是跨平台的,但是如果信息不可用,则应使用对象目录视图(sys。*)而不是系统表视图(在SQL Server中已弃用) 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

我的代码确实假设,因为这就是发问者的要求-“我正在通过约束的名称来获取[是否存在'给定的默认约束']”。我已经对答案进行了编辑,以使其直接满足问题的性质更加清晰。希望有帮助。
ErikE

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
我几个小时以来一直在搜索这个简单的查询。Thannnnkkkk youuuu!
塞缪尔

区分大小写的数据库应该有o.xtype ='D'才能工作。
IvanH

37

Information_Schema视图中似乎没有默认约束名称。

用于SELECT * FROM sysobjects WHERE xtype = 'D' AND name = @name 通过名称查找默认约束


正是我所需要的。谢谢
drdwilcox

直接回答问题要好于以后的选择(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
留出更多的空格将是不错的选择,但这确实符合原始发布者使用对象目录视图(sys。*)所要求的内容,Microsoft在反向兼容系统表视图上建议使用该对象目录视图。
罗伯特·卡尔洪

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

死灵法师。
如果只需要检查是否存在
默认约束(在管理不善的数据库中默认约束的名称可能不同),请
使用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不包含有关默认约束的任何信息。
斯蒂芬·特纳

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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.