By: Tim Ford | Updated: 2008-06-04 | Comments (7) | Related: 1 | 2 | 3 | 4 | 5 | 6 | 7 | More > Scripts
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
About the author
This author pledges the content of this article is based on professional experience and not AI generated.
View all my tips
Article Last Updated: 2008-06-04