【问题标题】:How do I find a default constraint using INFORMATION_SCHEMA?如何使用 INFORMATION_SCHEMA 找到默认约束?
【发布时间】:2010-09-13 14:09:46
【问题描述】:

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

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

他们不在那里吗? (我使用的是 MS SQL Server 2000)。

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

【问题讨论】:

    标签: sql sql-server tsql information-schema


    【解决方案1】:

    INFORMATION_SCHEMA.COLUMNS 的 COLUMN_DEFAULT 列是您要查找的内容吗?

    【讨论】:

    • 是也不是,它告诉我有一个默认值以及它是什么,但我也需要约束的名称。
    • 另外,请注意,如果您的运行时 SQL 登录名不拥有 dbo 架构,您可能只能在 COLUMN_DEFAULT 列中找到 NULL 值。
    【解决方案2】:

    我认为它不在 INFORMATION_SCHEMA 中 - 您可能必须使用 sysobjects 或相关的已弃用表/视图。

    你会认为在 INFORMATION_SCHEMA.TABLE_CONSTRAINTS 中会有一个这样的类型,但我没有看到。

    【讨论】:

      【解决方案3】:

      可能是因为在其他一些 SQL DBMS 上,“默认约束”并不是真正的约束,您不会在“INFORMATION_SCHEMA.TABLE_CONSTRAINTS”中找到它的名称,所以最好的选择是“INFORMATION_SCHEMA.COLUMNS”,就像其他人一样已经提到了。

      (此处为 SQLServer-ignoramus)

      当您必须知道“默认约束”的名称时,我能想到的唯一原因是 SQLServer 不支持 "ALTER TABLE xxx ALTER COLUMN yyy SET DEFAULT..." 命令。但是你已经在一个非标准区域,你必须使用特定于产品的方式来获得你需要的东西。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 正是我所需要的。谢谢
        • 比后来的替代方案更好地直接回答问题(SQL 2000 和按约束名称查询)。
        • 这仅在您知道约束名称但系统分配的情况下才有效....
        【解决方案5】:

        您可以通过指定与默认约束相关的表名和列名,使用以下方法进一步缩小结果范围:

        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'
        

        【讨论】:

        • 我搜索这个简单的查询已经有几个小时了。 Thannnnnkkk youuuu !
        • 应该有 o.xtype = 'D' 才能工作是区分大小写的数据库。
        【解决方案6】:

        如何使用 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 不包含任何有关默认约束的信息。
        【解决方案7】:
        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
        

        【讨论】:

        • 多一点空白会很好,但这可以满足原始发帖人使用对象目录视图 (sys.*) 的要求,Microsoft 建议使用对象目录视图,而不是向后兼容的系统表视图。
        【解决方案8】:

        下面的脚本列出了运行它的数据库中用户表的所有默认约束和默认值:

        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
        

        【讨论】:

          【解决方案9】:

          据我了解,默认值约束不是 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'
          

          【讨论】:

          • 注意:在不同的模式中可能有相同的表名,所以你也应该加入 sys.schemas 表。
          • @DanielJamesBryars sys.schemas 现已添加到查询中。
          • 请参阅my answer,它简短而实用,适用于所有版本的 SQL Server,没有任何 sys 表,并且易于记忆。
          • @ErikE 您的代码假定默认约束的名称是已知的。正如您的代码所示,这是一个很容易解决的问题。好的答案,错误的问题。
          • 我的代码确实假设了这一点,因为这就是提问者所要求的——“我希望通过约束的名称来获取 [是否存在'给定的默认约束']。”我已经编辑了我的答案,使其直接满足问题的性质更加清晰。希望对您有所帮助。
          【解决方案10】:

          如果您想通过列名或表名获取约束,或者您想获取数据库中的所有约束,请查看其他答案。但是,如果您只是在寻找问题的确切内容,即“测试给定的默认约束是否存在......按约束的名称”,那么有一个更简单的方法.

          这是一个完全不使用sysobjects 或其他sys 表的面向未来的答案:

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

          【讨论】:

            【解决方案11】:

            我正在使用以下脚本来检索所有默认值 (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 = ''
            

            【讨论】:

              【解决方案12】:
              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 
              

              【讨论】:

                【解决方案13】:

                对象目录视图: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;
                

                【讨论】:

                  【解决方案14】:

                  死灵术。
                  如果您只需要检查是否存在默认约束
                  (默认约束在管理不善的数据库中可能有不同的名称),
                  使用 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'
                  */
                  

                  【讨论】:

                    【解决方案15】:

                    一种更简洁的方法:

                    SELECT DC.[name]
                      FROM [sys].[default_constraints] AS DC
                      WHERE DC.[parent_object_id] = OBJECT_ID('[Schema].[TableName]') 
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2020-12-11
                      • 2012-06-18
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多