How do I find a default constraint using INFORMATION_SCHEMA?

SqlSql ServerTsqlInformation Schema

Sql Problem Overview


I'm trying to test if a given default constraint exists. I don't want to use the sysobjects table, but the more standard INFORMATION_SCHEMA.

I've used this to check for tables and primary key constraints before, but I don't see default constraints anywhere.

Are they not there? (I'm using MS SQL Server 2000).

EDIT: I'm looking to get by the name of the constraint.

Sql Solutions


Solution 1 - Sql

As I understand it, default value constraints aren't part of the ISO standard, so they don't appear in INFORMATION_SCHEMA. INFORMATION_SCHEMA seems like the best choice for this kind of task because it is cross-platform, but if the information isn't available one should use the object catalog views (sys.*) instead of system table views, which are deprecated in SQL Server 2005 and later.

Below is pretty much the same as @user186476's answer. It returns the name of the default value constraint for a given column. (For non-SQL Server users, you need the name of the default in order to drop it, and if you don't name the default constraint yourself, SQL Server creates some crazy name like "DF_TableN_Colum_95AFE4B5". To make it easier to change your schema in the future, always explicitly name your constraints!)

-- 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'

Solution 2 - Sql

You can use the following to narrow the results even more by specifying the Table Name and Column Name that the Default Constraint correlates to:

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'

Solution 3 - Sql

There seems to be no Default Constraint names in the Information_Schema views.

use SELECT * FROM sysobjects WHERE xtype = 'D' AND name = @name to find a default constraint by name

Solution 4 - Sql

The script below lists all the default constraints and the default values for the user tables in the database in which it is being run:

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

Solution 5 - Sql

If you want to get a constraint by the column or table names, or you want to get all the constraints in the database, look to other answers. However, if you're just looking for exactly what the question asks, namely, to "test if a given default constraint exists ... by the name of the constraint", then there's a much easier way.

Here's a future-proof answer that doesn't use the sysobjects or other sys tables at all:

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

Solution 6 - Sql

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

Solution 7 - Sql

Is the COLUMN_DEFAULT column of INFORMATION_SCHEMA.COLUMNS what you are looking for?

Solution 8 - Sql

Necromancing.
If you only need to check if a default-constraint exists
(default-constraint(s) may have different name in poorly-managed DBs),
use 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 

If you want to check by the constraint-name only:

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

And last but not least, you can just create a view called
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'
*/

Solution 9 - Sql

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 

Solution 10 - Sql

I don't think it's in the INFORMATION_SCHEMA - you'll probably have to use sysobjects or related deprecated tables/views.

You would think there would be a type for this in INFORMATION_SCHEMA.TABLE_CONSTRAINTS, but I don't see one.

Solution 11 - Sql

Probably because on some of the other SQL DBMSs the "default constraint" is not really a constraint, you'll not find its name in "INFORMATION_SCHEMA.TABLE_CONSTRAINTS", so your best bet is "INFORMATION_SCHEMA.COLUMNS" as others have mentioned already.

(SQLServer-ignoramus here)

The only a reason I can think of when you have to know the "default constraint"'s name is if SQLServer doesn't support "ALTER TABLE xxx ALTER COLUMN yyy SET DEFAULT..." command. But then you are already in a non-standard zone and you have to use the product-specific ways to get what you need.

Solution 12 - Sql

How about using a combination of CHECK_CONSTRAINTS and 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

Solution 13 - Sql

I am using folllowing script to retreive all defaults (sp_binddefaults) and all default constraint with following scripts:

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 = ''

Solution 14 - Sql

Object Catalog View : sys.default_constraints

The information schema views INFORMATION_SCHEMA are ANSI-compliant, but the default constraints aren't a part of ISO standard. Microsoft SQL Server provides system catalog views for getting information about SQL Server object metadata.

sys.default_constraints system catalog view used to getting the information about 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;

Solution 15 - Sql

A bit of a cleaner way to do this:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWildJoeView Question on Stackoverflow
Solution 1 - SqlRobert CalhounView Answer on Stackoverflow
Solution 2 - SqlTim LentineView Answer on Stackoverflow
Solution 3 - SqldevioView Answer on Stackoverflow
Solution 4 - SqlJohan BadenhorstView Answer on Stackoverflow
Solution 5 - SqlErikEView Answer on Stackoverflow
Solution 6 - Sqluser186476View Answer on Stackoverflow
Solution 7 - Sqluser12861View Answer on Stackoverflow
Solution 8 - SqlStefan SteigerView Answer on Stackoverflow
Solution 9 - Sqluser3059720View Answer on Stackoverflow
Solution 10 - SqlCade RouxView Answer on Stackoverflow
Solution 11 - SqlMilen A. RadevView Answer on Stackoverflow
Solution 12 - SqlBenderfishView Answer on Stackoverflow
Solution 13 - SqlMirecView Answer on Stackoverflow
Solution 14 - SqleigenharshaView Answer on Stackoverflow
Solution 15 - SqlSerj SaganView Answer on Stackoverflow