335

I have this sql:

ALTER TABLE dbo.ChannelPlayerSkins
    DROP CONSTRAINT FK_ChannelPlayerSkins_Channels

but apparently, on some other databases we use, the constraint has a different name. How do I check if there's a constraint with the name FK_ChannelPlayerSkins_Channels.

KM.
  • 101,727
  • 34
  • 178
  • 212
Lieven Cardoen
  • 25,140
  • 52
  • 153
  • 244
  • http://geekswithblogs.net/deadlydog/archive/2012/09/14/sql-server-script-commands-to-check-if-object-exists-and.aspx – gotqn Apr 12 '13 at 07:10
  • 2
    Many of the answers here fail when the same constraint name is used on multiple objects or in another schema. – Mark Schultheiss Feb 21 '19 at 13:25

15 Answers15

426

try this:

SELECT
    * 
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS 
    WHERE CONSTRAINT_NAME ='FK_ChannelPlayerSkins_Channels'

-- EDIT --

When I originally answered this question, I was thinking "Foreign Key" because the original question asked about finding "FK_ChannelPlayerSkins_Channels". Since then many people have commented on finding other "constraints" here are some other queries for that:

--Returns one row for each CHECK, UNIQUE, PRIMARY KEY, and/or FOREIGN KEY
SELECT * 
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    WHERE CONSTRAINT_NAME='XYZ'  


--Returns one row for each FOREIGN KEY constrain
SELECT * 
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS 
    WHERE CONSTRAINT_NAME='XYZ'


--Returns one row for each CHECK constraint 
SELECT * 
    FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS
    WHERE CONSTRAINT_NAME='XYZ'

here is an alternate method

--Returns 1 row for each CHECK, UNIQUE, PRIMARY KEY, FOREIGN KEY, and/or DEFAULT
SELECT 
    OBJECT_NAME(OBJECT_ID) AS NameofConstraint
        ,SCHEMA_NAME(schema_id) AS SchemaName
        ,OBJECT_NAME(parent_object_id) AS TableName
        ,type_desc AS ConstraintType
    FROM sys.objects
    WHERE type_desc LIKE '%CONSTRAINT'
        AND OBJECT_NAME(OBJECT_ID)='XYZ'

If you need even more constraint information, look inside the system stored procedure master.sys.sp_helpconstraint to see how to get certain information. To view the source code using SQL Server Management Studio get into the "Object Explorer". From there you expand the "Master" database, then expand "Programmability", then "Stored Procedures", then "System Stored Procedures". You can then find "sys.sp_helpconstraint" and right click it and select "modify". Just be careful to not save any changes to it. Also, you can just use this system stored procedure on any table by using it like EXEC sp_helpconstraint YourTableNameHere.

KM.
  • 101,727
  • 34
  • 178
  • 212
  • 3
    One thing to note, in my SQL to add the constraint, I used brackets around the name like, [fk_Client_ProjectID_Project]. You MUST remove the brackets in the WHERE clause. – ScubaSteve Jun 18 '13 at 13:33
  • 2
    There's nothing wrong in brackets. This is a SQL Server question, not a MySQL one. – Álvaro González Feb 25 '14 at 17:45
  • 1
    If it's a Unique Constraint you need a slightly different version: IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_NAME = 'UNIQUE_Order_ExternalReferenceId') BEGIN ALTER TABLE Order ADD CONSTRAINT UNIQUE_Order_ExternalReferenceId UNIQUE (ExternalReferenceId) END – The Coder Apr 15 '14 at 21:00
  • 3
    The above didn't work for a unique column constraint (SQL2008). I had to use the following: SELECT * FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE WHERE CONSTRAINT_NAME='UC_constraintName' – Alan B. Dee Aug 19 '14 at 00:05
  • 1
    For default constraints, only the alternate method listed returns a row. – ChargingPun Oct 22 '15 at 11:22
  • @ChargingPun, yep, each query will return the values listed in the comment. "Default" is only listed in the "alternate method". – KM. Oct 23 '15 at 17:59
  • Just note that quering `INFORMATION_SCHEMA` or `sys.objects` in principle is orders of magnitude slower that `OBJECT_ID`/`OBJECTPROPERTY` system functions approach (which use cached metadata). Might be worth it to refactor when patch scripts get humongous after 10s of years of development, for instance. – wqw Jul 12 '17 at 13:36
310

Easiest way to check for the existence of a constraint (and then do something such as drop it if it exists) is to use the OBJECT_ID() function...

IF OBJECT_ID('dbo.[CK_ConstraintName]', 'C') IS NOT NULL 
    ALTER TABLE dbo.[tablename] DROP CONSTRAINT CK_ConstraintName

OBJECT_ID can be used without the second parameter ('C' for check constraints only) and that may also work, but if your constraint name matches the name of other objects in the database you may get unexpected results.

IF OBJECT_ID('dbo.[CK_ConstraintName]') IS NOT NULL 
    ALTER TABLE dbo.[tablename] DROP CONSTRAINT CK_ConstraintName

OBJECT_ID can also be used with other "constraints" such as Foreign Key constraints or Primary Key constraints, etc. For best results, always include the appropriate object type as the second parameter for the OBJECT_ID function:

Constraint Object Types:

  • C = CHECK constraint
  • D = DEFAULT (constraint or stand-alone)
  • F = FOREIGN KEY constraint
  • PK = PRIMARY KEY constraint
  • R = Rule (old-style, stand-alone)
  • UQ = UNIQUE constraint

Also note that the schema is often required. The schema of constraints generally takes the schema of the parent table.

Failure to put your constraints (or whatever you are checking) in brackets when using this method may also cause a false negative -- if your object uses unusual characters (such as a .), the brackets are required.

bvoyelr
  • 920
  • 8
  • 11
EricI
  • 3,636
  • 1
  • 16
  • 8
  • 19
    The important thing is to add schema name in the parameter to OBJECT_ID like this: IF OBJECT_ID('dbo.CK_ConstraintName', 'C') IS NOT NULL. Without specifying schema it returns NULL. – gator88 Apr 14 '14 at 10:07
  • Hi, thanks for your answer, it's really helpful. Just wondering if it applies for Oracle? –  Oct 03 '14 at 03:21
  • Does not work on sql2000. Just use `OBJECTPROPERTY(OBJECT_ID('constraint_name'), 'IsConstraint') = 1` to be compatible from current version all the way to sql2000. No `dbo` schema required too. – wqw Jul 12 '17 at 13:33
48

If you are looking for other type of constraint, e.g. defaults, you should use different query (From How do I find a default constraint using INFORMATION_SCHEMA? answered by devio). Use:

SELECT * FROM sys.objects WHERE type = 'D' AND name = @name

to find a default constraint by name.

I've put together different 'IF not Exists" checks in my post "DDL 'IF not Exists" conditions to make SQL scripts re-runnable"

Community
  • 1
  • 1
Michael Freidgeim
  • 26,542
  • 16
  • 152
  • 170
31
IF (OBJECT_ID('FK_ChannelPlayerSkins_Channels') IS NOT NULL)
DevDave
  • 6,700
  • 12
  • 65
  • 99
  • It turns out I had to add the schema name, see https://stackoverflow.com/questions/29680286/why-can-i-not-find-a-foreign-key-using-the-object-id-function – Johan Maes Apr 01 '19 at 07:27
20

Are you looking at something like this, below is tested in SQL Server 2005

SELECT * FROM sys.check_constraints WHERE 
object_id = OBJECT_ID(N'[dbo].[CK_accounts]') AND 
parent_object_id = OBJECT_ID(N'[dbo]. [accounts]')
asyncwait
  • 4,457
  • 4
  • 40
  • 53
9

Just something to watch out for......

In SQL Server 2008 R2 SSMS, the "Script Constraint as -> DROP And CREATE To" command produces T-SQL like below

USE [MyDatabase]
GO

IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DEF_Detail_IsDeleted]') AND type = 'D')
BEGIN
ALTER TABLE [Patient].[Detail] DROP CONSTRAINT [DEF_Detail_IsDeleted]
END

GO

USE [MyDatabase]
GO

ALTER TABLE [Patient].[Detail] ADD  CONSTRAINT [DEF_Detail_IsDeleted]  DEFAULT ((0)) FOR [IsDeleted]
GO

Out of the box, this script does NOT drop the constraint because the SELECT returns 0 rows. (see post Microsoft Connect).

The name of the default constraint is wrong but I gather it also has something to do with the OBJECT_ID function because changing the name doesn't fix the problem.

To fix this, I removed the usage of OBJECT_ID and used the default constraint name instead.

(SELECT * FROM dbo.sysobjects WHERE [name] = (N'DEF_Detail_IsDeleted') AND type = 'D')
Mike1234
  • 139
  • 1
  • 4
  • 2
    Looks like the script doesn't schema qualify the name. Would be safer to use `OBJECT_ID(N'[YourSchema].[DEF_Detail_IsDeleted]')` in case you have 2 constraints of the same name in different schemas. – Martin Smith Jun 21 '12 at 22:11
8

I use the following query to check for an existing constraint before I create it.

IF (NOT EXISTS(SELECT 1 FROM sysconstraints WHERE OBJECT_NAME(constid) = 'UX_CONSTRAINT_NAME' AND OBJECT_NAME(id) = 'TABLE_NAME')) BEGIN
...
END

This queries for the constraint by name targeting a given table name. Hope this helps.

Christo
  • 2,330
  • 3
  • 24
  • 37
4
IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.TableName'))
 BEGIN 
ALTER TABLE TableName DROP CONSTRAINT CONSTRAINTNAME 
END 
StackOrder
  • 270
  • 4
  • 14
4
IF EXISTS(SELECT TOP 1 1 FROM sys.default_constraints WHERE parent_object_id = OBJECT_ID(N'[dbo].[ChannelPlayerSkins]') AND name = 'FK_ChannelPlayerSkins_Channels')
BEGIN
    DROP CONSTRAINT FK_ChannelPlayerSkins_Channels
END
GO
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
3

INFORMATION_SCHEMA is your friend. It has all kinds of views that show all kinds of schema information. Check your system views. You will find you have three views dealing with constraints, one being CHECK_CONSTRAINTS.

Suraj Kumar
  • 5,547
  • 8
  • 20
  • 42
TomTom
  • 61,059
  • 10
  • 88
  • 148
2

As of SQL Server 2016, you can just use the IF EXISTS keywords.

ALTER TABLE dbo.ChannelPlayerSkins
    DROP CONSTRAINT IF EXISTS FK_ChannelPlayerSkins_Channels

I'm using SQL Server 2019, but this mentions that it was available since SQL Server 2016.

The SQL Server docs mention it here under the ALTER TABLE page, and not under this Delete Check Constraints page. I'm not sure why.

IF EXISTS Applies to: SQL Server (SQL Server 2016 (13.x) and later) and Azure SQL Database. Conditionally drops the column or constraint only if it already exists.

shmuels
  • 1,039
  • 1
  • 9
  • 22
1

I use this to check for and remote constraints on a column. It should have everything you need.

DECLARE
  @ps_TableName VARCHAR(300)
  , @ps_ColumnName VARCHAR(300)

SET @ps_TableName = 'mytable'
SET @ps_ColumnName = 'mycolumn'

DECLARE c_ConsList CURSOR LOCAL STATIC FORWARD_ONLY FOR
    SELECT
    'ALTER TABLE ' + RTRIM(tb.name) + ' drop constraint ' + sco.name AS csql
    FROM
        sys.Objects tb
        INNER JOIN sys.Columns tc on (tb.Object_id = tc.object_id)
        INNER JOIN sys.sysconstraints sc ON (tc.Object_ID = sc.id and tc.column_id = sc.colid)
        INNER JOIN sys.objects sco ON (sc.Constid = sco.object_id)
    where
        tb.name=@ps_TableName
        AND tc.name=@ps_ColumnName
OPEN c_ConsList
FETCH c_ConsList INTO @ls_SQL
WHILE (@@FETCH_STATUS = 0) BEGIN

    IF RTRIM(ISNULL(@ls_SQL, '')) <> '' BEGIN
        EXECUTE(@ls_SQL)
    END
    FETCH c_ConsList INTO @ls_SQL
END
CLOSE c_ConsList
DEALLOCATE c_ConsList
Leigh
  • 28,765
  • 10
  • 55
  • 103
0
SELECT tabla.name as Tabla,

        restriccion.name as Restriccion, 
        restriccion.type as Tipo, 
        restriccion.type_desc as Tipo_Desc
FROM {DATABASE_NAME}.sys.objects tabla 

INNER JOIN {DATABASE_NAME}.sys.objects restriccion

ON tabla.object_id = restriccion.parent_object_id

WHERE tabla.type = 'U' - Solo tablas creadas por el usuario.

AND restriccion.type = 'UQ' --Tipo de Restriccion UNIQUE

ORDER BY tabla.name, restriccion.type_desc                
Sanoob
  • 2,466
  • 4
  • 30
  • 38
  • 1
    This answer would be more useful if there were some explanation along with it, rather than just dumping code. – Sam Hanley Oct 28 '14 at 17:57
  • 1
    To second @sphanley: You answer an old question that has already several well received answers. Please explain what it is better or at least specific about your answer so that it is worth posting. – honk Oct 28 '14 at 18:11
0

You can use the one above with one caveat:

IF EXISTS(
    SELECT 1 FROM sys.foreign_keys 
    WHERE parent_object_id = OBJECT_ID(N'dbo.TableName') 
        AND name = 'CONSTRAINTNAME'
)
BEGIN 
    ALTER TABLE TableName DROP CONSTRAINT CONSTRAINTNAME 
END 

Need to use the name = [Constraint name] since a table may have multiple foreign keys and still not have the foreign key being checked for

Saša
  • 4,416
  • 1
  • 27
  • 41
alaniane
  • 92
  • 1
  • 5
0

In mySql you need to make sure you are querying the right database! Hence table_schema=DATABASE()

Here are my functions using knex to check if a specific Foreign Key or Index defined in specific database and table

const isFKExists = async (knex, tableName, fkName) => {
  const result = await knex.raw(
    `SELECT COUNT(*) AS 'isExists' FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_schema=DATABASE() AND table_name='${tableName}' AND CONSTRAINT_NAME='${fkName}' AND CONSTRAINT_TYPE = 'FOREIGN KEY'`
  )
  return (result[0][0].isExists === 1)
}

const isIndexExists = async (knex, tableName, indexName) => {
  const result = await knex.raw(
    `SELECT COUNT(*) AS 'isExists' FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() AND table_name='${tableName}' AND index_name='${indexName}'`
  )
  return (result[0][0].isExists > 0)
}

Enjoy

Oz Ben-David
  • 1,589
  • 1
  • 16
  • 26