如何检查Sql服务器中是否存在约束?

发布于 2024-08-25 19:28:31 字数 224 浏览 10 评论 0原文

我有这个 sql:

ALTER TABLE dbo.ChannelPlayerSkins
    DROP CONSTRAINT FK_ChannelPlayerSkins_Channels

但显然,在我们使用的其他一些数据库上,约束有不同的名称。如何检查是否存在名为 FK_ChannelPlayerSkins_Channels 的约束。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

无力看清 2024-09-01 19:28:31

试试这个:

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

-- 编辑 --

当我最初回答这个问题时,我在想“外键”,因为最初的问题询问如何查找“FK_ChannelPlayerSkins_Channels”。从那时起,许多人都评论说要寻找其他“约束”,这里有一些其他查询:

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

这是一种替代方法

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

如果您需要更多约束信息,请查看系统存储过程master.sys.sp_helpconstraint 查看如何获取某些信息。要使用 SQL Server Management Studio 查看源代码,请进入“对象资源管理器”。从那里展开“主”数据库,然后展开“可编程性”,然后展开“存储过程”,然后展开“系统存储过程”。然后您可以找到“sys.sp_helpconstraint”并右键单击它并选择“修改”。只是要小心不要保存任何更改。此外,您可以通过像 EXEC sp_helpconstraint YourTableNameHere 这样的方式在任何表上使用此系统存储过程。

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.

人生戏 2024-09-01 19:28:31

检查约束是否存在的最简单方法(然后执行一些操作,例如如果存在则删除它)是使用 OBJECT_ID() 函数...

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

OBJECT_ID 可以在没有第二个参数的情况下使用(“C”仅用于检查约束)这也可能有效,但如果您的约束名称与数据库中其他对象的名称匹配,您可能会得到意外的结果。

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

OBJECT_ID 还可以与其他“约束”一起使用,例如外键约束或主键约束等。为了获得最佳结果,请始终包含适当的对象类型作为 OBJECT_ID 函数的第二个参数:

约束对象类型:

  • C = CHECK 约束
  • D = DEFAULT(约束或独立)
  • F = FOREIGN KEY 约束
  • PK = PRIMARY KEY 约束
  • R = 规则(旧式、独立)
  • UQ = UNIQUE 约束

另请注意,通常需要模式。约束的模式通常采用父表的模式。

使用此方法时未能将约束(或您正在检查的任何内容)放在括号中也可能会导致漏报 - 如果您的对象使用不寻常的字符(例如 .),则需要括号。

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.

剩一世无双 2024-09-01 19:28:31

如果您正在寻找其他类型的约束,例如默认值,您应该使用不同的查询
(来自 如何找到默认值使用 INFORMATION_SCHEMA 约束?devio 回答)。用途:

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

按名称查找默认约束。

我在我的帖子“DDL 'IF not Exists' 条件使 SQL 脚本可重新运行"

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"

森林散布 2024-09-01 19:28:31
IF (OBJECT_ID('FK_ChannelPlayerSkins_Channels') IS NOT NULL)
IF (OBJECT_ID('FK_ChannelPlayerSkins_Channels') IS NOT NULL)
妄断弥空 2024-09-01 19:28:31

你在看这样的东西吗,下面是在 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]')

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]')
原野 2024-09-01 19:28:31

只是需要注意......

在 SQL Server 2008 R2 SSMS 中,“脚本约束为 -> DROP And CREATE To”命令生成如下所示的 T-SQL

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

开箱即用,此脚本不会删除约束,因为 SELECT 返回 0 行。 (请参阅帖子 Microsoft Connect)。

默认约束的名称是错误的,但我认为它也与 OBJECT_ID 函数有关,因为更改名称并不能解决问题。

为了解决这个问题,我删除了 OBJECT_ID 的使用并使用默认约束名称。

(SELECT * FROM dbo.sysobjects WHERE [name] = (N'DEF_Detail_IsDeleted') AND type = 'D')

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')
你好,陌生人 2024-09-01 19:28:31

在创建约束之前,我使用以下查询来检查现有约束。

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

这按针对给定表名称的名称查询约束。希望这有帮助。

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.

挽你眉间 2024-09-01 19:28:31

从 SQL Server 2016 开始,您可以仅使用 IF EXISTS 关键字。

ALTER TABLE dbo.ChannelPlayerSkins
    DROP CONSTRAINT IF EXISTS FK_ChannelPlayerSkins_Channels

我使用的是 SQL Server 2019,但是 提到它自 SQL Server 2016 起就可用。SQL

Server 文档提到它此处位于 ALTER TABLE 页面下,而不是位于 删除检查约束页面。我不知道为什么。

如果存在
适用于:SQL Server(SQL Server 2016 (13.x) 及更高版本)和 Azure SQL 数据库。
仅当列或约束已存在时才有条件地删除它。

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.

飘逸的'云 2024-09-01 19:28:31
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 
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 
岁月打碎记忆 2024-09-01 19:28:31
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
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
黄昏下泛黄的笔记 2024-09-01 19:28:31

INFORMATION_SCHEMA 是您的朋友。它具有显示各种模式信息的各种视图。检查您的系统视图。您会发现有三个处理约束的视图,其中一个是CHECK_CONSTRAINTS

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.

别闹i 2024-09-01 19:28:31

我用它来检查列上的远程约束。它应该有你需要的一切。

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

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
倒带 2024-09-01 19:28:31
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                
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                
度的依靠╰つ 2024-09-01 19:28:31

您可以使用上面的方法,但有一点需要注意:

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 

需要使用 name = [Constraint name],因为表可能有多个外键,但仍然没有检查外键

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

死开点丶别碍眼 2024-09-01 19:28:31

在 mySql 中,您需要确保查询正确的数据库!
因此 table_schema=DATABASE()

这是我使用 knex 来检查特定数据库和表中是否定义了特定外键或索引的函数

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

享受

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 ????

与他有关 2024-09-01 19:28:31

应该是通用代码..使用这里许多答案的想法.. &在 SQL Server 2016 上进行测试。- AE 2024

DECLARE @table_id varchar(50), @con_name varchar(100);

Select @table_id = OBJECT_ID(N'[dbo].[ChannelPlayerSkins]');

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = @table_id AND type in (N'U'))
BEGIN
    SELECT @con_name = name FROM sys.objects WHERE type = 'F'
    AND name LIKE('FK__ChannelPl__Chann__%')
    AND parent_object_id = @table_id;

    if not (@con_name is null)
        exec('ALTER TABLE [mes].[SQL_MAPSTORE] DROP CONSTRAINT [' + @con_name + ']');
END
GO

Should be the universal code.. using ideas from a number of answers here.. & testing on SQL Server 2016. - AE 2024

DECLARE @table_id varchar(50), @con_name varchar(100);

Select @table_id = OBJECT_ID(N'[dbo].[ChannelPlayerSkins]');

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = @table_id AND type in (N'U'))
BEGIN
    SELECT @con_name = name FROM sys.objects WHERE type = 'F'
    AND name LIKE('FK__ChannelPl__Chann__%')
    AND parent_object_id = @table_id;

    if not (@con_name is null)
        exec('ALTER TABLE [mes].[SQL_MAPSTORE] DROP CONSTRAINT [' + @con_name + ']');
END
GO
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文