Learn more about SQL Server tools

mssqltips logo
 

Tutorials          DBA          Dev          BI          Career          Categories          Webcasts          Whitepapers          Today's Tip          Join

Tutorials      DBA      Dev      BI      Categories      Webcasts

DBA    Dev    BI    Categories

 

Finding and listing all columns in a SQL Server database with default values


By:   |   Read Comments (6)   |   Related Tips: 1 | 2 | 3 | 4 | 5 | 6 | 7 | More > Scripts

Attend our free MSSQLTips Webcast - How to Simplify Routine SQL Server Administration Tasks


Problem
I was troubleshooting an issue last week on a vendor-developed database when they stated we needed to look at each one of the 50 tables in their database to make sure that all fields expecting default values, had default values assigned.  Well, you can imaging how daunting a task that would be and I immediately raised the question:  "Don't you have a better way to do this other than to open each table in SQL Server Management Studio to review the schema?"  Their answer was a polite, but firm "No".  At that point I decided to change their mind...

Solution
By querying three system tables in any database you can get the default value for each column of every table.  Below is the core query.  It returns the default value assigned to every user table in the current database.  This query is compatible with both SQL 2000 and SQL 2005.

SELECT SO.NAME AS "Table Name", SC.NAME AS "Column Name", SM.TEXT AS "Default Value"
FROM dbo.sysobjects SO INNER JOIN dbo.syscolumns SC ON SO.id SC.id 
LEFT JOIN dbo.syscomments SM ON SC.cdefault SM.id 
WHERE SO.xtype 'U' 
ORDER BY SO.[name]SC.colid 

The sysobjects table provides us with the table metadata.  In this case we're only interested in the table name.  The syscolumns table stores metadata related to the individual columns for each table.  In this example, we only require the column name.  Finally, the default value metadata is provided courtesy of the syscomments table.

Running this query against the Northwind database yields the following results.  (Some rows omitted for brevity.)  Notice that it will return NULL default values due to the LEFT JOIN on the syscomments table.

Now my thoughts turned to what options existed for a tweaked version of the base query...

Option 1:  Search for Specific Default Values

By editing the WHERE clause slightly, we can look for specific default values across all tables.

SELECT SO.NAME AS "Table Name", SC.NAME AS "Column Name", SM.TEXT AS "Default Value"
FROM dbo.sysobjects SO INNER JOIN dbo.syscolumns SC ON SO.id SC.id 
LEFT 
JOIN dbo.syscomments SM ON SC.cdefault SM.id 
WHERE SO.xtype 'U' AND SM.TEXT = '(0)'
ORDER BY SO.[name]SC.colid 
 

Option 2:  Return Information on Only Columns with Default Values

Modifying the core query's WHERE clause to omit NULL values in the syscomments.text table would do the trick here:

SELECT SO.NAME AS "Table Name", SC.NAME AS "Column Name", SM.TEXT AS "Default Value"
FROM dbo.sysobjects SO INNER JOIN dbo.syscolumns SC ON SO.id SC.id 
LEFT 
JOIN dbo.syscomments SM ON SC.cdefault SM.id 
WHERE SO.xtype 'U' AND SM.TEXT IS NOT NULL
ORDER BY SO.[name]SC.colid 
 

however, better optimization occurs why altering the JOIN in the FROM clause from a LEFT JOIN to an INNER JOIN:

SELECT SO.NAME AS "Table Name", SC.NAME AS "Column Name", SM.TEXT AS "Default Value"
FROM dbo.sysobjects SO INNER JOIN dbo.syscolumns SC ON SO.id SC.id 
INNER JOIN dbo.syscomments SM ON SC.cdefault SM.id 
WHERE SO.xtype 'U'
ORDER BY SO.[name]SC.colid

There is yet one other option entirely, taking advantage of the system catalog views in SQL 2005.  While the previous queries provided me with the information I needed at the time, and worked in both SQL 2000 and SQL 2005, there is additional metadata relating to the default value (in actuality, a default constraint) to be mined out of a SQL 2000 instance.  By basing the query exclusively on system catalog views we can get additional information not displayed in the previous queries.

SELECT ST.[name] AS "Table Name", SC.[name] AS "Column Name", SD.definition AS "Default Value", SD.[name] AS "Constraint Name"
FROM sys.tables ST INNER JOIN sys.syscolumns SC ON ST.[object_id] SC.[id] 
INNER JOIN 
sys.default_constraints SD ON ST.[object_id] SD.[parent_object_id] AND SC.colid SD.parent_column_id
ORDER BY ST.[name]SC.colid

So remember, just because you're told there is no better way, rely on your instincts as a DBA and dig in.  You never know what you may come up with.

Next Steps

  • Review other tips on system catalog views.
  • Look at the other catalog views for your database objects.
  • Review the other columns available in sys.default_constraints


Last Update:


signup button

next tip button



About the author





Post a comment or let the author know this tip helped.

All comments are reviewed, so stay on subject or we may delete your comment. Note: your email address is not published. Required fields are marked with an asterisk (*).

*Name    *Email    Notify for updates 


SQL tips:

*Enter Code refresh code     



Wednesday, October 17, 2012 - 8:35:20 AM - JT02451 Back To Top

Any idea how to do a column_name,count(*) on ALL columns on ALL tables within a database schema?  Must it be done cursively with a script or TransactSQL, or can it be done in a single query?  I'd be interested in writing the results to a table.  Thanks


Thursday, August 30, 2012 - 12:01:45 AM - jadav suresh Back To Top

how to find spacific column in alll database.

 

plz solve my problem.

 

 


Friday, July 25, 2008 - 12:14:07 AM - sean.x.li Back To Top

I think this is also workable in SQL 2K


Sunday, June 15, 2008 - 11:15:34 AM - 24Seven Back To Top

 There is a far simpler technique in SQL 2005+

Select *
From INFORMATION_SCHEMA.COLUMNS
Where COLUMN_DEFAULT Is Not Null


Wednesday, June 11, 2008 - 12:39:14 AM - impala Back To Top

how about this one?

 

SELECT t.name AS TableName,

c.name AS ColumnName,

ty.name AS ColumnType,

c.length AS Length,

c.isnullable AS AllowNulls,

CASE WHEN EXISTS (SELECT TOP 1 indid FROM sysindexkeys WHERE id = t.id AND indid = colid AND colid = c.colid AND keyno=c.colid)

THEN 1 ELSE 0 END AS IsPrimaryKey,

lower(isnull((select top 1 substring(text, 2, len(text) -2) from syscomments (NOLOCK) where id = c.cdefault), '')) AS DefaultValue

FROM sysobjects t (NOLOCK),

syscolumns c (NOLOCK),

systypes ty (NOLOCK)

WHERE c.id = t.id

AND c.xtype = ty.xusertype

and t.xtype='U'

and t.name <> 'dtproperties'

ORDER BY t.name, c.colorder


Thursday, June 05, 2008 - 12:15:20 AM - Ignacio de Tomas Back To Top

Really very useful


Learn more about SQL Server tools