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

1
@DanielJamesBryars sys.schemasがクエリに追加されました。
スティーブンターナー

短くて甘い、SQL Serverのすべてのバージョンで機能し、テーブルがなく、覚えやすい私の回答をご覧くださいsys
ErikE 2015

2
@ErikEコードでは、デフォルトの制約の名前がわかっていることを前提としています。コードが示すように、これは簡単に解決できる問題です。良い答え、間違った質問。
DarLom

それは質問者が求めたものであるため、私のコードはそれを前提としています。私は自分の回答を編集して、直接的な質問を満たす性質をより明確にしました。お役に立てば幸いです。
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
数時間後、私はこの単純なクエリを検索します。たんんんんっっく
Samuel

大文字と小文字を区別するデータベースを機能させるには、o.xtype = 'D'が必要です。
IvanH 2013年

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
もう少し空白がいいでしょうが、これは元の投稿者がオブジェクトカタログビュー(sys。*)を使用して求めたものです。これは、下位互換性のあるシステムテーブルビューよりもMicrosoftによって推奨されています。
ロバートカルホーン

2

INFORMATION_SCHEMA.COLUMNSのCOLUMN_DEFAULT列は探しているものですか?


はい、いいえ、それはデフォルトがあることとそれが何であるかを教えてくれますが、制約の名前も必要です。
WildJoe 2008

1
また、ランタイムSQLログインがdboスキーマを所有していない場合は、COLUMN_DEFAULT列にNULL値しか見つからない場合があることに注意してください。
グレンリトル

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.