Query to find out the stored procedure depending on a column - sql

I have to change the name and the datatype of a column of a table. I have about 150 stored procedures in the database, out of which about 25 refer to the same column. I need a query that can find the name of all the stored procedures which are dependent on this column.

I use this query:
SELECT OBJECT_NAME(M.object_id), M.*
FROM sys.sql_modules M
JOIN sys.procedures P
ON M.object_id = P.object_id
WHERE M.definition LIKE '%blah%'
Obviously you'd have to substitute "blah" for the name of your column.

Try this 1
From Sp
SELECT Name as [Stored Procedure Name]
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%getdate%' order by Name
From Table
SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%EmployeeID%'
ORDER BY schema_name, table_name;

Problem:
As you know there is no way to query what fields are referenced by a function or stored procedure.
The closest we can get is an approximation.
We can tell which tables are referenced and what fields might possibly be referenced by those tables.
For example, if you have "CreatedDate" referenced by the "Person" table and you join to the "Order" table (which also has a "CreatedDate" field), it will find a “false-positive” match to "Order.CreatedDate" when you were only looking for "Person.CreatedDate".
Searching the Text of the object's script for field names is unfortunately the best we can do for now.
The good news is, it won’t miss identifying fields that are actually used.
If anything it might pull in more than what were used (due to shared field names or commented out code).
The only exception would be dynamic SQL, as Tables are not linked to Object Scripts if they are embedded in a dynamic string.
Workaround:
CREATE FUNCTION [dbo].[ft_Schema_Column_Script]
(
#ScriptName nVarChar(128) = '%',
#TableName nVarChar(128) = '%',
#ColumnName nVarChar(128) = '%'
)
RETURNS TABLE
AS
RETURN
(
SELECT ##SERVERNAME[ServerName], DB_NAME()[DatabaseName],
SS.name[ScriptSchemaName], SO.name[ScriptName],
SO.type_desc[ScriptType],
TS.name[TableSchemaName], T.name[TableName], C.name[ColumnName],
UT.name[ColumnType], C.max_length[MaxLength],
C.precision[NumericPrecision], C.scale[Scale],
C.is_nullable[Nullable],
C.is_identity[IsIdentity],
C.column_id[Ordinal],
EP.value[Description]
FROM sys.sql_modules as M
JOIN sys.objects as SO--Script Object.
ON M.object_id = SO.object_id
JOIN sys.schemas as SS--Script Schema.
ON SS.schema_id = SO.schema_id
JOIN sys.sql_expression_dependencies D
ON D.referencing_id = SO.object_id
JOIN sys.tables as T
ON T.object_id = D.referenced_id
JOIN sys.schemas as TS--Table Schema.
ON TS.schema_id = T.schema_id
JOIN sys.columns as C
ON C.object_id = T.object_id
LEFT JOIN sys.types AS UT--Left Join because of user-defined/newer types.
ON UT.user_type_id = C.user_type_id
LEFT JOIN sys.extended_properties AS EP
ON EP.major_id = C.object_id
AND EP.minor_id = C.column_id
AND EP.name = 'MS_Description'
WHERE T.name LIKE #TableName ESCAPE '\'
AND C.name LIKE #ColumnName ESCAPE '\'
AND SO.name LIKE #ScriptName ESCAPE '\'
--Use RegEx to exclude false-posotives by from similar ColumnNames.
-- (e.g. Ignore the "ModifiedBy" field when matching on "Modified").
-- Use C.name instead of #ColumnName to further reduce false-positives.
AND M.definition LIKE ( N'%[ ~`!##$\%\^&*()+-=\[\]\\{}|;'''':",./<>?]'
+ C.name
+ N'[ ~`!##$\%\^&*()+-=\[\]\\{}|;'''':",./<>?]%'
) ESCAPE '\'
)
GO
Test:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM dbo.ft_Schema_Column_Script('ScriptName', DEFAULT, DEFAULT) as C
SELECT * FROM dbo.ft_Schema_Column_Script(DEFAULT, 'TableName', DEFAULT) as C
SELECT * FROM dbo.ft_Schema_Column_Script(DEFAULT, DEFAULT, 'ColumnName') as C
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
Test the example above to see if it's good enough to meet your needs.
Results:
Example output when running this function searching for the Column Name "Created".
It searches Stored Procedures (Sprocs), User-Defined-Functions (UDF's), Triggers, but not Jobs.
The cool thing is:
This not only searches for Columns referenced by Scripts,but also Scripts referenced by Columns (or Tables)!

-- Search in All Objects
SELECT OBJECT_NAME(OBJECT_ID),
definition
FROM sys.sql_modules
WHERE definition LIKE '%' + 'BusinessEntityID' + '%'

Search in Stored Procedures Only:
SELECT DISTINCT OBJECT_NAME(OBJECT_ID),
object_definition(OBJECT_ID)
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%' + 'BusinessEntityID' + '%'

Related

Find the column names of Temp table

I need to find the column names of temp table.
If it is a physical table then we can either use sys.columns or Information_schema.columns system views to find the column names.
Similarly is there a way to find the column names present in temp table?
SELECT *
FROM tempdb.sys.columns
WHERE object_id = Object_id('tempdb..#sometemptable');
To get only columns name you can use this query below:
SELECT *
FROM tempdb.sys.columns
WHERE [object_id] = OBJECT_ID(N'tempdb..#temp');
To get columns name with data type you can use this query but you need to make sure sp_help runs in the same database where the table is located (tempdb).
EXEC tempdb.dbo.sp_help #objname = N'#temp';
you can achieve same result by joining against tempdb.sys.columns like below:
SELECT [column] = c.name,
[type] = t.name, c.max_length, c.precision, c.scale, c.is_nullable
FROM tempdb.sys.columns AS c
INNER JOIN tempdb.sys.types AS t
ON c.system_type_id = t.system_type_id
AND t.system_type_id = t.user_type_id
WHERE [object_id] = OBJECT_ID(N'tempdb.dbo.#temp');

Find references to one database's columns in all other databases

I want these 5 columns as output when a stored procedure, in any database on the server, references a column in a specific database (let's say the database is AA).
Column_name Table_Name Schema_Name Procedure_Name Database_Name
Four of the columns are really easy to get - for the current database that you're in:
SELECT
TableName = t.Name,
SchemaName = s.Name,
ColumnName = c.Name,
DatabaseName = DB_NAME()
FROM
sys.tables t
INNER JOIN
sys.schemas s ON [t].[schema_id] = [s].[schema_id]
INNER JOIN
sys.columns c ON [t].[object_id] = [c].[object_id]
What you cannot get easily is all columns across all tables in all databases. Also: determining in which procedure each column is used is also rather tricky (or next to impossible).
From marc_s answer i generate a query which gives comma separated Procedure_Name depended by that table
SELECT
TableName = t.Name,
SchemaName = s.Name,
ColumnName = c.Name,
DatabaseName = DB_NAME(),
STUFF((SELECT ',' + name
FROM sys.procedures
WHERE object_id in (SELECT distinct id from sys.sysdepends
WHERE depid = (SELECT object_id FROM sys.tables
WHERE name=t.Name)
)
FOR XML PATH('')), 1, 0, '') AS sps
FROM
sys.tables t
INNER JOIN
sys.schemas s ON [t].[schema_id] = [s].[schema_id]
INNER JOIN
sys.columns c ON [t].[object_id] = [c].[object_id]

how to create XML schema from an existing database in SQL Server 2008

Is there a way to create an XML schema from an existing database in SQL Server 2008, SQL Server Management Studio?
I have a DB with ~50 tables. I'm looking to create a "nice" diagram showing the relationship between those tables. Using another application called SQL Designer (https://code.google.com/p/wwwsqldesigner/) will give me the "nice" looking picture, but I don't know how to create the XML schema required.
I did a search across the forum (and MS) and couldn't quite find my answer. I could find tools which created a database, but I'm looking at the reverse... I need a pretty picture which shows the database in diagrammatic form. I thought if I could get my db structure into XML then SQL Designer will do the rest for me.
Thanks for your assistance.
Nick
If you only need the xml schema of tables query them with this:
select top 0 * FROM daTable FOR XML AUTO,XMLSCHEMA
If you need the table names and columns in order to create a representation of your database and how tables are connected you can use something like this:
SELECT
s.name as '#Schema'
,t.name as '#Name'
,t.object_id as '#Id'
,(
SELECT c.name as '#Name'
,c.column_id as '#Id'
,IIF(ic.object_id IS NOT NULL,1,0) as '#IsPrimaryKey'
,fkc.referenced_object_id as '#ColumnReferencesTableId'
,fkc.referenced_column_id as '#ColumnReferencesTableColumnId'
FROM sys.columns as c
LEFT OUTER JOIN sys.index_columns as ic
ON c.object_id = ic.object_id
AND c.column_id = ic.column_id
AND ic.index_id = 1
LEFT OUTER JOIN sys.foreign_key_columns as fkc
ON c.object_id = fkc.parent_object_id
AND c.column_id = fkc.parent_column_id
WHERE c.object_id = t.object_id
FOR XML PATH ('Column'),TYPE
)
FROM sys.schemas as s
INNER JOIN sys.tables as t
ON s.schema_id = t.schema_id
FOR XML PATH('Table'),ROOT('Tables')
Let your application use the ColumnReferencesTableId and ColumnReferencesTableColumnId to get table relations. You could also further join back to columns and tables which are referenced if you prefer writing their names out but I thought their Ids would suffice.
Combined with a cursor running through INFORMATION_SCHEMA or sysobjects, the following should help you:
SELECT * FROM [MyTable] FOR XML AUTO, XMLSCHEMA
I'm uncertain as to whether you can simply apply this to a whole database, or what postprocessing effort would be required to combine all the various table schemas, but it's something to work with.
Try this (a variation of this answer):
DECLARE #listStr VARCHAR(MAX)
SELECT #listStr = COALESCE(#listStr+',' ,'') + TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
EXEC('
DECLARE #schema xml
SET #schema = (SELECT TOP 0 * FROM ' +
#listStr +
' FOR XML AUTO, ELEMENTS, XMLSCHEMA(''DbSchema''))
SELECT #schema
');
Replace the line:
,**IIF**(ic.object_id IS NOT NULL,1,0) as '#IsPrimaryKey'
With this:
,CASE WHEN ic.object_id IS NOT NULL THEN 1 ELSE 0 END AS '#IsPrimaryKey'
for MS SQL server versions not allowing the IIF function.

SQL Server search for a column by name

I'm doing some recon work and having to dig through a few hundred SQL Server database tables to find columns.
Is there a way to easily search for columns in the database and return just the table name that the column belongs to?
I found this, but that also returns Stored procedures with that column name in it...
SELECT OBJECT_NAME(object_id) FROM sys.columns WHERE name = 'foo'
This includes views though but can be further filtered . It may be useful though.
More generally...
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'foo'
sys.columns
To get the
1) full column name
2) object name (including schema)
3) object type (table/view)
4) data type (nice format: varchar(6) or numeric(5,2), etc.)
5) null/not null
6) information on identity, check constraint, and default info
try this:
DECLARE #Search varchar(200)
SET #Search='YourColumnName' --can be a partial or a complete name
SELECT
s.name as ColumnName
,sh.name+'.'+o.name AS ObjectName
,o.type_desc AS ObjectType
,CASE
WHEN t.name IN ('char','varchar') THEN t.name+'('+CASE WHEN s.max_length<0 then 'MAX' ELSE CONVERT(varchar(10),s.max_length) END+')'
WHEN t.name IN ('nvarchar','nchar') THEN t.name+'('+CASE WHEN s.max_length<0 then 'MAX' ELSE CONVERT(varchar(10),s.max_length/2) END+')'
WHEN t.name IN ('numeric') THEN t.name+'('+CONVERT(varchar(10),s.precision)+','+CONVERT(varchar(10),s.scale)+')'
ELSE t.name
END AS DataType
,CASE
WHEN s.is_nullable=1 THEN 'NULL'
ELSE 'NOT NULL'
END AS Nullable
,CASE
WHEN ic.column_id IS NULL THEN ''
ELSE ' identity('+ISNULL(CONVERT(varchar(10),ic.seed_value),'')+','+ISNULL(CONVERT(varchar(10),ic.increment_value),'')+')='+ISNULL(CONVERT(varchar(10),ic.last_value),'null')
END
+CASE
WHEN sc.column_id IS NULL THEN ''
ELSE ' computed('+ISNULL(sc.definition,'')+')'
END
+CASE
WHEN cc.object_id IS NULL THEN ''
ELSE ' check('+ISNULL(cc.definition,'')+')'
END
AS MiscInfo
FROM sys.columns s
INNER JOIN sys.types t ON s.system_type_id=t.system_type_id and t.is_user_defined=0
INNER JOIN sys.objects o ON s.object_id=o.object_id
INNER JOIN sys.schemas sh on o.schema_id=sh.schema_id
LEFT OUTER JOIN sys.identity_columns ic ON s.object_id=ic.object_id AND s.column_id=ic.column_id
LEFT OUTER JOIN sys.computed_columns sc ON s.object_id=sc.object_id AND s.column_id=sc.column_id
LEFT OUTER JOIN sys.check_constraints cc ON s.object_id=cc.parent_object_id AND s.column_id=cc.parent_column_id
WHERE s.name LIKE '%'+#Search+'%'
select c.name as ColumnName, o.name as TableName
from sys.columns c
inner join sys.objects o on c.object_id = o.object_id
where c.name = 'MyColumnName'
http://www.red-gate.com/products/SQL_Search/index.htm?utm_source=google&utm_medium=cpc&utm_content=brand_aware&utm_campaign=sqlsearch&gclid=COSfqe_mmKQCFSE1gwodSxOrEQ
This should do it for you. I use it everyday.
This stored procedure will search for table.name and column.name pairs.
I use when I have "WhateverId" in code and I want to know where that is (probably) stored in the database without actually having to read through and understand the code. :)
CREATE OR ALTER PROC FindColumns
#ColumnName VARCHAR(MAX) = NULL,
#TableName VARCHAR(MAX) = NULL
AS
SELECT T.[name] AS TableName, C.[name] AS ColumnName
FROM sys.all_columns C
JOIN sys.tables T ON C.object_id = T.object_id
JOIN sys.types CT ON C.user_type_id = CT.user_type_id
WHERE (#ColumnName IS NULL OR C.[name] LIKE '%' + TRIM(#ColumnName) + '%')
AND (#TableName IS NULL OR T.[name] LIKE '%' + TRIM(#TableName) + '%')
ORDER BY T.[name], C.[name]
select table_name from information_schema.columns
where column_name = '<your column name here>'
Using the information_schema views is 'more correct' as system details in the system databases are subject to change between implementations of SQL Server.

How do I find a default constraint using INFORMATION_SCHEMA?

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.
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'
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'
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
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
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
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
Is the COLUMN_DEFAULT column of INFORMATION_SCHEMA.COLUMNS what you are looking for?
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'
*/
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
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.
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.
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
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 = ''
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;
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]')
If the target database has, say, over 1M objects, using sys.default_constraints can hit you with 90%+ taken on scanning sys.syscolpars followed by a Key Lookup for the dflt you likely don't care about. On my DB, it takes 1.129s to assemble just 4 rows from the 158 read of the residual I/O impaired 1.12MM rows actually scanned.
Changing to using the current sys.% tables/views, using #Tim's query, the same 4 constraints are acquired in 2ms. Hope someone finds this as useful as I found Tim's:
SELECT ConstraintName = sdc.name
, SchemaName = ssch.name
, TableName = stab.name
, ColumnName = scol.name
FROM sys.objects sdc
INNER JOIN sys.columns scol
ON scol.default_object_id = sdc.object_id
INNER JOIN sys.objects stab
ON stab.object_id = scol.object_id
INNER JOIN sys.schemas ssch
ON ssch.schema_id = stab.schema_id;