How to find which indexes and constraints contain a specific column? - sql

I am planing a database change and I have a list of columns included in process. Can I list all indexes in which is a specific column included?
Edit
So far I have (combined from answers):
declare #TableName nvarchar(128), #FieldName nvarchar(128)
select #TableName= N'<<Table Name>>', #FieldName =N'<<Field Name>>'
(SELECT distinct systab.name AS TABLE_NAME,sysind.name AS INDEX_NAME, 'index'
FROM sys.indexes sysind
INNER JOIN sys.index_columns sysind_col
ON sysind.object_id = sysind_col.object_id and sysind.index_id = sysind_col.index_id
INNER JOIN sys.columns sys_col
ON sysind_col.object_id = sys_col.object_id and sysind_col.column_id = sys_col.column_id
INNER JOIN sys.tables systab
ON sysind.object_id = systab.object_id
WHERE systab.is_ms_shipped = 0 and sysind.is_primary_key=0 and sys_col.name =#FieldName and systab.name=#TableName
union
select t.name TABLE_NAME,o.name, 'Default' OBJ_TYPE
from sys.objects o
inner join sys.columns c on o.object_id = c.default_object_id
inner join sys.objects t on c.object_id = t.object_id
where o.type in ('D') and c.name =#FieldName and t.name=#TableName
union
SELECT u.TABLE_NAME,u.CONSTRAINT_NAME, 'Constraint' OBJ_TYPE
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE u
where u.COLUMN_NAME = #FieldName and u.TABLE_NAME = #TableName
) order by 1
But I am not too happy with combining of sys. and 'INFORMATION_SCHEMA.' Can it be avoided?

---Using sp_helpindex and your TableName
exec sp_helpindex YourTableName
---Using sys.tables with your TableName and ColumnName
select distinct c.name, i.name, i.type_desc,...
from sys.indexes i
join sys.index_columns ic on i.index_id = ic.index_id
join sys.columns c on ic.column_id = c.column_id
where i.object_id = OBJECT_ID(N'YourTableName') and c.name = 'YourColumnName'
EDIT: As per comment, you can also join object_Ids without using distinct
select c.name, i.name, i.type_desc
from sys.indexes i
join sys.index_columns ic on i.index_id = ic.index_id and i.object_id = ic.object_id
join sys.columns c on ic.column_id = c.column_id and ic.object_id = c.object_id
where i.object_id = OBJECT_ID(N'YourTableName') and c.name = 'YourColumnName'

SELECT * FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
USE TABLE_NAME IN WHERE if you what to know the constraint on a table.
and use column_name if you know the column name.

To get information regarding all indexes in which is a specific column is included following two catalog views can be used:
sys.indexes , sys.index_columns
Query:
SELECT
sysind.name AS INDEX_NAME
,sysind.index_id AS INDEX_ID
,sys_col.name AS COLUMN_NAME
,systab.name AS TABLE_NAME
FROM sys.indexes sysind
INNER JOIN sys.index_columns sysind_col
ON sysind.object_id = sysind_col.object_id and sysind.index_id = sysind_col.index_id
INNER JOIN sys.columns sys_col
ON sysind_col.object_id = sys_col.object_id and sysind_col.column_id = sys_col.column_id
INNER JOIN sys.tables systab
ON sysind.object_id = systab.object_id
WHERE (1=1)
AND systab.is_ms_shipped = 0
AND sys_col.name IN(specific column list for which indexes are to be queried)
ORDER BY
systab.name,sys_col.name, sysind.name,sysind.index_id
Hope this helps!

If you have access to the sys schema on your database then you can query sys.indexes to get the index ID and use that with the function index_col to get the columns. The final parameter for index_col is the index of the column within the index (i.e. if there are 3 columns in the index you would have to call index_col 3 times with 1, 2, 3 in the last parameter)
select index_id from sys.indexes
where object_id = object_id(#objectname)
select index_col(#objectname, #indexid, 1)
This should give you constraints as well as they are just special indexes.

Related

Extract Foreign Key Constraint and Reference Column from SQL Server table's query

I use the following query to list all table constraints, which works well in extracting constraint needed to alter the output table (adding primary key, unique constraint).
select table_view,
object_type,
constraint_type,
constraint_name,
details
from (
select schema_name(t.schema_id) + '.' + t.[name] as table_view,
case when t.[type] = 'U' then 'Table'
when t.[type] = 'V' then 'View'
end as [object_type],
case when c.[type] = 'PK' then 'Primary key'
when c.[type] = 'UQ' then 'Unique constraint'
when i.[type] = 1 then 'Unique clustered index'
when i.type = 2 then 'Unique index'
end as constraint_type,
isnull(c.[name], i.[name]) as constraint_name,
substring(column_names, 1, len(column_names)-1) as [details]
from sys.objects t
left outer join sys.indexes i
on t.object_id = i.object_id
left outer join sys.key_constraints c
on i.object_id = c.parent_object_id
and i.index_id = c.unique_index_id
cross apply (select col.[name] + ', '
from sys.index_columns ic
inner join sys.columns col
on ic.object_id = col.object_id
and ic.column_id = col.column_id
where ic.object_id = t.object_id
and ic.index_id = i.index_id
order by col.column_id
for xml path ('') ) D (column_names)
where is_unique = 1
and t.is_ms_shipped <> 1
union all
select schema_name(fk_tab.schema_id) + '.' + fk_tab.name as foreign_table,
'Table',
'Foreign key',
fk.name as fk_constraint_name,
schema_name(pk_tab.schema_id) + '.' + pk_tab.name
from sys.foreign_keys fk
inner join sys.tables fk_tab
on fk_tab.object_id = fk.parent_object_id
inner join sys.tables pk_tab
on pk_tab.object_id = fk.referenced_object_id
inner join sys.foreign_key_columns fk_cols
on fk_cols.constraint_object_id = fk.object_id
union all
select schema_name(t.schema_id) + '.' + t.[name],
'Table',
'Check constraint',
con.[name] as constraint_name,
con.[definition]
from sys.check_constraints con
left outer join sys.objects t
on con.parent_object_id = t.object_id
left outer join sys.all_columns col
on con.parent_column_id = col.column_id
and con.parent_object_id = col.object_id
union all
select schema_name(t.schema_id) + '.' + t.[name],
'Table',
'Default constraint',
con.[name],
col.[name] + ' = ' + con.[definition]
from sys.default_constraints con
left outer join sys.objects t
on con.parent_object_id = t.object_id
left outer join sys.all_columns col
on con.parent_column_id = col.column_id
and con.parent_object_id = col.object_id) a
order by table_view, constraint_type, constraint_name
https://dataedo.com/kb/query/sql-server/list-all-table-constraints
However, it does not work in case of foreign key as a foreign key constraint (column) and its reference column is needed.
ALTER TABLE row16.table_view
ADD CONSTRAINT row16.contraint_name
FOREIGN KEY (**row16....**) REFERENCES row16.details(**row16....**);
|| actual value
ALTER TABLE DBO.AREA
ADD CONSTRAINT FK_AREA_DOM_AIRLINE
FOREIGN KEY (**should be 'airline_cd'**) REFERENCES DBO.DOM_AIRLINE(**should be 'cd'**);
I wanted to add foreign constraint using the following statement, but I don't know how I could define foreign key constraint and its reference column here..
I feel like there might be a need to make some changes to the table constraints query, but I just start learning SQL recently so I'm not familiar with the whole concept yet...
Here's table relation for reference
Please let me know if you need any more infos. Appreciated all your helps!

SQL Search for a Binary value

I've seen similar queries where a string or character value is used to search an entire database. Those queries do not return results that lie in a BINARY(8) field. I've tried to modify those queries to no avail.
Is there a way to search the entire database for specific binary values, such as 0x0000000000000017?
Thanks guys.
You can use the system tables to find this.
MSSQL:
SELECT t.name AS table_name,
c.name AS column_name,
ty.name
FROM sys.tables AS t
INNER JOIN sys.columns c
ON t.OBJECT_ID = c.OBJECT_ID
INNER JOIN sys.types ty
ON t.schema_id = ty.schema_id
WHERE ty.system_type_id = 173
ORACLE:
SELECT owner,table_name, column_name,data_TYPE
FROM all_tab_columns where data_TYPE = 'RAW';
Well...
select *
from foo
where foo.binary8column = 0x0000000000000017
should do. If you want to enumerate all the tables and find all the binary or varbinary columns, this query
select table_name = object_schema_name(tn.object_id) + '.' + tn.name ,
column_name = c.name ,
type = t.name + '(' + convert(varchar,c.max_length) + ')'
from sys.types t
join sys.columns c on c.system_type_id = t.system_type_id
join sys.tables tn on tn.object_id = c.object_id
where t.name in ( 'binary', 'varbinary' )
and c.max_length >= 8
should give enough information to generate the queries for every such table.

How can I find out what FOREIGN KEY constraint references a table in SQL Server?

I am trying to drop a table but getting the following message:
Msg 3726, Level 16, State 1, Line 3
Could not drop object 'dbo.UserProfile' because it is referenced by a FOREIGN KEY constraint.
Msg 2714, Level 16, State 6, Line 2
There is already an object named 'UserProfile' in the database.
I looked around with SQL Server Management Studio but I am unable to find the constraint. How can I find out the foreign key constraints?
Here it is:
SELECT
OBJECT_NAME(f.parent_object_id) TableName,
COL_NAME(fc.parent_object_id,fc.parent_column_id) ColName
FROM
sys.foreign_keys AS f
INNER JOIN
sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN
sys.tables t
ON t.OBJECT_ID = fc.referenced_object_id
WHERE
OBJECT_NAME (f.referenced_object_id) = 'YourTableName'
This way, you'll get the referencing table and column name.
Edited to use sys.tables instead of generic sys.objects as per comment suggestion.
Thanks, marc_s
Another way is to check the results of
sp_help 'TableName'
(or just highlight the quoted TableName and press ALT+F1)
With time passing, I just decided to refine my answer. Below is a screenshot of the results that sp_help provides. A have used the AdventureWorksDW2012 DB for this example. There is numerous good information there, and what we are looking for is at the very end - highlighted in green:
Try this
SELECT
object_name(parent_object_id) ParentTableName,
object_name(referenced_object_id) RefTableName,
name
FROM sys.foreign_keys
WHERE parent_object_id = object_id('Tablename')
I found this answer quite simple and did the trick for what I needed: https://stackoverflow.com/a/12956348/652519
A summary from the link, use this query:
EXEC sp_fkeys 'TableName'
Quick and simple. I was able to locate all the foreign key tables, respective columns and foreign key names of 15 tables pretty quickly.
As #mdisibio noted below, here's a link to the documentation that details the different parameters that can be used: https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-fkeys-transact-sql
Here is the best way to find out Foreign Key Relationship in all Database.
exec sp_helpconstraint 'Table Name'
and one more way
select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME='Table Name'
--and left(CONSTRAINT_NAME,2)='FK'(If you want single key)
I am using this script to find all details related to foreign key.
I am using INFORMATION.SCHEMA.
Below is a SQL Script:
SELECT
ccu.table_name AS SourceTable
,ccu.constraint_name AS SourceConstraint
,ccu.column_name AS SourceColumn
,kcu.table_name AS TargetTable
,kcu.column_name AS TargetColumn
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
ON ccu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
ON kcu.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME
ORDER BY ccu.table_name
if you want to go via SSMS on the object explorer window, right click on the object you want to drop, do view dependencies.
SELECT
obj.name AS FK_NAME,
sch.name AS [schema_name],
tab1.name AS [table],
col1.name AS [column],
tab2.name AS [referenced_table],
col2.name AS [referenced_column]
FROM
sys.foreign_key_columns fkc
INNER JOIN sys.objects obj
ON obj.object_id = fkc.constraint_object_id
INNER JOIN sys.tables tab1
ON tab1.object_id = fkc.parent_object_id
INNER JOIN sys.schemas sch
ON tab1.schema_id = sch.schema_id
INNER JOIN sys.columns col1
ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
INNER JOIN sys.tables tab2
ON tab2.object_id = fkc.referenced_object_id
INNER JOIN sys.columns col2
ON col2.column_id = referenced_column_id
AND col2.object_id = tab2.object_id;
In SQL Server Management Studio you can just right click the table in the
object explorer and select "View Dependencies". This would give a you a
good starting point. It shows tables, views, and procedures that reference
the table.
In Object Explorer, expand the table, and expand the Keys:
--The following may give you more of what you're looking for:
create Procedure spShowRelationShips
(
#Table varchar(250) = null,
#RelatedTable varchar(250) = null
)
as
begin
if #Table is null and #RelatedTable is null
select object_name(k.constraint_object_id) ForeginKeyName,
object_name(k.Parent_Object_id) TableName,
object_name(k.referenced_object_id) RelatedTable,
c.Name RelatedColumnName,
object_name(rc.object_id) + '.' + rc.name RelatedKeyField
from sys.foreign_key_columns k
left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
order by 2,3
if #Table is not null and #RelatedTable is null
select object_name(k.constraint_object_id) ForeginKeyName,
object_name(k.Parent_Object_id) TableName,
object_name(k.referenced_object_id) RelatedTable,
c.Name RelatedColumnName,
object_name(rc.object_id) + '.' + rc.name RelatedKeyField
from sys.foreign_key_columns k
left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
where object_name(k.Parent_Object_id) =#Table
order by 2,3
if #Table is null and #RelatedTable is not null
select object_name(k.constraint_object_id) ForeginKeyName,
object_name(k.Parent_Object_id) TableName,
object_name(k.referenced_object_id) RelatedTable,
c.Name RelatedColumnName,
object_name(rc.object_id) + '.' + rc.name RelatedKeyField
from sys.foreign_key_columns k
left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
where object_name(k.referenced_object_id) =#RelatedTable
order by 2,3
end
You could use this query to display Foreign key constaraints:
SELECT
K_Table = FK.TABLE_NAME,
FK_Column = CU.COLUMN_NAME,
PK_Table = PK.TABLE_NAME,
PK_Column = PT.COLUMN_NAME,
Constraint_Name = C.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
INNER JOIN (
SELECT i1.TABLE_NAME, i2.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
) PT ON PT.TABLE_NAME = PK.TABLE_NAME
---- optional:
ORDER BY
1,2,3,4
WHERE PK.TABLE_NAME='YourTable'
Taken from http://blog.sqlauthority.com/2006/11/01/sql-server-query-to-display-foreign-key-relationships-and-name-of-the-constraint-for-each-table-in-database/
You can also return all the information about the Foreign Keys by adapating #LittleSweetSeas answer:
SELECT
OBJECT_NAME(f.parent_object_id) ConsTable,
OBJECT_NAME (f.referenced_object_id) refTable,
COL_NAME(fc.parent_object_id,fc.parent_column_id) ColName
FROM
sys.foreign_keys AS f
INNER JOIN
sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN
sys.tables t
ON t.OBJECT_ID = fc.referenced_object_id
order by
ConsTable
The easiest way to get Primary Key and Foreign Key for a table is:
/* Get primary key and foreign key for a table */
USE DatabaseName;
SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE CONSTRAINT_NAME LIKE 'PK%' AND
TABLE_NAME = 'TableName'
SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE CONSTRAINT_NAME LIKE 'FK%' AND
TABLE_NAME = 'TableName'
try the following query.
select object_name(sfc.constraint_object_id) AS constraint_name,
OBJECT_Name(parent_object_id) AS table_name ,
ac1.name as table_column_name,
OBJECT_name(referenced_object_id) as reference_table_name,
ac2.name as reference_column_name
from sys.foreign_key_columns sfc
join sys.all_columns ac1 on (ac1.object_id=sfc.parent_object_id and ac1.column_id=sfc.parent_column_id)
join sys.all_columns ac2 on (ac2.object_id=sfc.referenced_object_id and ac2.column_id=sfc.referenced_column_id)
where sfc.parent_object_id=OBJECT_ID(<main table name>);
this will give the constraint_name, column_names which will be referring and tables which will be depending on the constraint will be there.
The procedure
_sp_help 'tbl_name'_
does give a lot of information but I find the procedures
_sp_fkeys 'tbl_name'_ and
_sp_pkeys 'tbl_name'_
easier to use, and maybe with a more future-proof result.
(And they do answer the OP perfectly)

Get index statistics information for tables referenced in a specific view

I'm trying to amend the following script to point at just the indexes associated with a particular view vw_foo. Is this possible?
SELECT name AS index_name,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes
Edit
When I say "associated" I mean the indexes on the underlying tables that are used to create the view
Possibly, it will be helpful for you -
SELECT
SCHEMA_NAME(o.[schema_id]) + '.' + o.name
, s.name
, statistics_update_date = STATS_DATE(o.[object_id], stats_id)
FROM sys.objects o
JOIN sys.stats s ON o.[object_id] = s.[object_id]
WHERE o.[type] = 'V' AND o.name = 'vw_foo'
DECLARE #table_name SYSNAME
SELECT #table_name = 'dbo.vw_foo'
EDITED
When I say "associated" I mean the indexes on the tables that are used
by the view
This query returns the list of the views where is used the specified table + shows additional info about the used index -
SELECT
o.table_name
, b.view_name
, i.name
, stast_updates = STATS_DATE(i.[object_id], i.index_id)
, dm_ius.last_user_seek
, dm_ius.last_user_scan
, dm_ius.last_user_lookup
, dm_ius.last_user_update
, dm_ius.user_updates
, dm_ius.user_lookups
, dm_ius.user_scans
, dm_ius.user_seeks
FROM (
SELECT
table_name = s.name + '.' + o.name
, o.[object_id]
FROM sys.objects o
JOIN sys.schemas s ON o.[schema_id] = s.[schema_id]
WHERE o.[type] = 'U'
AND s.name + '.' + o.name = #table_name
) o
JOIN sys.indexes i ON o.[object_id] = i.[object_id]
AND i.[type] > 0
AND i.is_disabled = 0
AND i.is_hypothetical = 0
LEFT JOIN sys.dm_db_index_usage_stats dm_ius ON i.index_id = dm_ius.index_id AND dm_ius.[object_id] = i.[object_id]
OUTER APPLY (
SELECT
view_name = r.referencing_schema_name + '.' + r.referencing_entity_name
, r.referencing_id
FROM sys.dm_sql_referencing_entities (o.table_name, 'OBJECT') r
JOIN sys.objects o2 ON r.referencing_id = o2.[object_id]
WHERE o2.[type] = 'V'
) b
WHERE b.view_name IS NOT NULL
The existing answers were probably heading towards checking the name in sys.objects but never do it. But there's no need to do so anyway, since the OBJECT_ID() function lets you get an object_id in a clean fashion:
SELECT name AS index_name,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes
WHERE object_id = OBJECT_ID('vw_foo')

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;