SQL Server search for a column by name - sql

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.

Related

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.

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

Query to find out the stored procedure depending on a column

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

SQL Server: Get table primary key using sql query [duplicate]

This question already has answers here:
How do you list the primary key of a SQL Server table?
(28 answers)
Closed 3 years ago.
I want to get a particular table's primary key using SQL query for SQL Server database.
In MySQL I am using following query to get table primary key:
SHOW KEYS FROM tablename WHERE Key_name = 'PRIMARY'
What is equivalent of above query for SQL Server ?.
If There is a query that will work for both MySQL and SQL Server then It will be an ideal case.
I also found another one for SQL Server:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)), 'IsPrimaryKey') = 1
AND TABLE_NAME = 'TableName' AND TABLE_SCHEMA = 'Schema'
Found another one:
SELECT
KU.table_name as TABLENAME
,column_name as PRIMARYKEYCOLUMN
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU
ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME
AND KU.table_name='YourTableName'
ORDER BY
KU.TABLE_NAME
,KU.ORDINAL_POSITION
;
I have tested this on SQL Server 2003/2005
Using SQL SERVER 2005, you can try
SELECT i.name AS IndexName,
OBJECT_NAME(ic.OBJECT_ID) AS TableName,
COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName
FROM sys.indexes AS i INNER JOIN
sys.index_columns AS ic ON i.OBJECT_ID = ic.OBJECT_ID
AND i.index_id = ic.index_id
WHERE i.is_primary_key = 1
Found at SQL SERVER – 2005 – Find Tables With Primary Key Constraint in Database
From memory, it's either this
SELECT * FROM sys.objects
WHERE type = 'PK'
AND object_id = OBJECT_ID ('tableName')
or this..
SELECT * FROM sys.objects
WHERE type = 'PK'
AND parent_object_id = OBJECT_ID ('tableName')
I think one of them should probably work depending on how the data is stored
but I am afraid I have no access to SQL to actually verify the same.
SELECT COLUMN_NAME FROM {DATABASENAME}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME LIKE '{TABLENAME}' AND CONSTRAINT_NAME LIKE 'PK%'
WHERE
{DATABASENAME} = your database from your server AND
{TABLENAME} = your table name from which you want to see the primary key.
NOTE : enter your database name and table name without brackets.
select *
from sysobjects
where xtype='pk' and
parent_obj in (select id from sysobjects where name='tablename')
this will work in sql 2005
The code I'll give you works and retrieves not only keys, but a lot of data from a table in SQL Server. Is tested in SQL Server 2k5/2k8, dunno about 2k. Enjoy!
SELECT DISTINCT
sys.tables.object_id AS TableId,
sys.columns.column_id AS ColumnId,
sys.columns.name AS ColumnName,
sys.types.name AS TypeName,
sys.columns.precision AS NumericPrecision,
sys.columns.scale AS NumericScale,
sys.columns.is_nullable AS IsNullable,
( SELECT
COUNT(column_name)
FROM
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
WHERE
TABLE_NAME = sys.tables.name AND
CONSTRAINT_NAME =
( SELECT
constraint_name
FROM
INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE
TABLE_NAME = sys.tables.name AND
constraint_type = 'PRIMARY KEY' AND
COLUMN_NAME = sys.columns.name
)
) AS IsPrimaryKey,
sys.columns.max_length / 2 AS CharMaxLength /*BUG*/
FROM
sys.columns, sys.types, sys.tables
WHERE
sys.tables.object_id = sys.columns.object_id AND
sys.types.system_type_id = sys.columns.system_type_id AND
sys.types.user_type_id = sys.columns.user_type_id AND
sys.tables.name = 'TABLE'
ORDER BY
IsPrimaryKey
You can use only the primary key part, but I think that the rest might become handy.
Best regards,
David
This should list all the constraints and at the end you can put your filters
/* CAST IS DONE , SO THAT OUTPUT INTEXT FILE REMAINS WITH SCREEN LIMIT*/
WITH ALL_KEYS_IN_TABLE (CONSTRAINT_NAME,CONSTRAINT_TYPE,PARENT_TABLE_NAME,PARENT_COL_NAME,PARENT_COL_NAME_DATA_TYPE,REFERENCE_TABLE_NAME,REFERENCE_COL_NAME)
AS
(
SELECT CONSTRAINT_NAME= CAST (PKnUKEY.name AS VARCHAR(30)) ,
CONSTRAINT_TYPE=CAST (PKnUKEY.type_desc AS VARCHAR(30)) ,
PARENT_TABLE_NAME=CAST (PKnUTable.name AS VARCHAR(30)) ,
PARENT_COL_NAME=CAST ( PKnUKEYCol.name AS VARCHAR(30)) ,
PARENT_COL_NAME_DATA_TYPE= oParentColDtl.DATA_TYPE,
REFERENCE_TABLE_NAME='' ,
REFERENCE_COL_NAME=''
FROM sys.key_constraints as PKnUKEY
INNER JOIN sys.tables as PKnUTable
ON PKnUTable.object_id = PKnUKEY.parent_object_id
INNER JOIN sys.index_columns as PKnUColIdx
ON PKnUColIdx.object_id = PKnUTable.object_id
AND PKnUColIdx.index_id = PKnUKEY.unique_index_id
INNER JOIN sys.columns as PKnUKEYCol
ON PKnUKEYCol.object_id = PKnUTable.object_id
AND PKnUKEYCol.column_id = PKnUColIdx.column_id
INNER JOIN INFORMATION_SCHEMA.COLUMNS oParentColDtl
ON oParentColDtl.TABLE_NAME=PKnUTable.name
AND oParentColDtl.COLUMN_NAME=PKnUKEYCol.name
UNION ALL
SELECT CONSTRAINT_NAME= CAST (oConstraint.name AS VARCHAR(30)) ,
CONSTRAINT_TYPE='FK',
PARENT_TABLE_NAME=CAST (oParent.name AS VARCHAR(30)) ,
PARENT_COL_NAME=CAST ( oParentCol.name AS VARCHAR(30)) ,
PARENT_COL_NAME_DATA_TYPE= oParentColDtl.DATA_TYPE,
REFERENCE_TABLE_NAME=CAST ( oReference.name AS VARCHAR(30)) ,
REFERENCE_COL_NAME=CAST (oReferenceCol.name AS VARCHAR(30))
FROM sys.foreign_key_columns FKC
INNER JOIN sys.sysobjects oConstraint
ON FKC.constraint_object_id=oConstraint.id
INNER JOIN sys.sysobjects oParent
ON FKC.parent_object_id=oParent.id
INNER JOIN sys.all_columns oParentCol
ON FKC.parent_object_id=oParentCol.object_id /* ID of the object to which this column belongs.*/
AND FKC.parent_column_id=oParentCol.column_id/* ID of the column. Is unique within the object.Column IDs might not be sequential.*/
INNER JOIN sys.sysobjects oReference
ON FKC.referenced_object_id=oReference.id
INNER JOIN INFORMATION_SCHEMA.COLUMNS oParentColDtl
ON oParentColDtl.TABLE_NAME=oParent.name
AND oParentColDtl.COLUMN_NAME=oParentCol.name
INNER JOIN sys.all_columns oReferenceCol
ON FKC.referenced_object_id=oReferenceCol.object_id /* ID of the object to which this column belongs.*/
AND FKC.referenced_column_id=oReferenceCol.column_id/* ID of the column. Is unique within the object.Column IDs might not be sequential.*/
)
select * from ALL_KEYS_IN_TABLE
where
PARENT_TABLE_NAME in ('YOUR_TABLE_NAME')
or REFERENCE_TABLE_NAME in ('YOUR_TABLE_NAME')
ORDER BY PARENT_TABLE_NAME,CONSTRAINT_NAME;
For reference please read thru - http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx
Keep in mind that if you want to get exact primary field you need to put TABLE_NAME and TABLE_SCHEMA into the condition.
this solution should work:
select COLUMN_NAME from information_schema.KEY_COLUMN_USAGE
where CONSTRAINT_NAME='PRIMARY' AND TABLE_NAME='TABLENAME'
AND TABLE_SCHEMA='DATABASENAME'
It is also (Transact-SQL) ... according to BOL.
-- exec sp_serveroption 'SERVER NAME', 'data access', 'true' --execute once
EXEC sp_primarykeys #table_server = N'server_name',
#table_name = N'table_name',
#table_catalog = N'db_name',
#table_schema = N'schema_name'; --frequently 'dbo'

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;