我有这样的SQL:如何检查Sql服务器中是否存在约束?
ALTER TABLE dbo.ChannelPlayerSkins
DROP CONSTRAINT FK_ChannelPlayerSkins_Channels
,但显然,在我们使用一些其他的数据库,约束具有不同的名称。如何检查名称FK_ChannelPlayerSkins_Channels
是否有限制。
我有这样的SQL:如何检查Sql服务器中是否存在约束?
ALTER TABLE dbo.ChannelPlayerSkins
DROP CONSTRAINT FK_ChannelPlayerSkins_Channels
,但显然,在我们使用一些其他的数据库,约束具有不同的名称。如何检查名称FK_ChannelPlayerSkins_Channels
是否有限制。
试试这个:
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查看源代码进入“对象资源管理器”。从那里展开“Master”数据库,然后展开“Programmability”,然后展开“Stored Procedures”,然后展开“System Stored Procedures”。然后您可以找到“sys.sp_helpconstraint”并右键单击它并选择“修改”。只是要小心不要保存任何更改。此外,您可以使用此系统存储过程在任何表上使用它,如EXEC sp_helpconstraint YourTableNameHere
。
有一点需要注意,在我的SQL中添加约束,我在名称周围使用了括号[fk_Client_ProjectID_Project]。您必须删除WHERE子句中的括号。 – ScubaSteve 2013-06-18 13:33:42
括号里没有错。这是一个SQL Server问题,而不是MySQL问题。 – 2014-02-25 17:45:48
如果它是一个独特的约束,你需要一个稍微不同的版本:IF NOT EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS其中CONSTRAINT_NAME = 'UNIQUE_Order_ExternalReferenceId') BEGIN \t ALTER TABLE订单 \t \t添加约束UNIQUE_Order_ExternalReferenceId \t \t UNIQUE(ExternalReferenceId) END – 2014-04-15 21:00:36
INFORMATION_SCHEMA是你的朋友。它具有显示各种模式信息的各种视图。检查你的系统视图。你会发现你有三个视图处理约束,一个是CHECK_CONSTRAINTS。
你看着这样的事情,下面是在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]')
如果您正在寻找其他类型的约束,例如默认值,你应该使用不同的查询 (从How do I find a default constraint using INFORMATION_SCHEMA?回答devio)。使用:
SELECT * FROM sys.objects WHERE type = 'D' AND name = @name
按名称查找默认约束。
我已经把不同的“IF NOT EXISTS “检查在我的岗位” DDL 'IF not Exists" conditions to make SQL scripts re-runnable"
sysobjects将在未来版本中删除。请使用sys.objects代替 – 2014-07-08 23:03:58
如果使用上面的查询,请注意sys.objects表没有xtype列,它应该是type。无法直接编辑答案,因为它是单字符更新(至少需要6个字符)。 – pennanth 2017-05-10 02:42:50
@ pennanth:谢谢,修正 – 2017-05-10 06:24:40
IF (OBJECT_ID('FK_ChannelPlayerSkins_Channels') IS NOT NULL)
只是要当心......
在SQL Server 2008 R2 SSMS ,“脚本约束为 - >删除并创建为”命令生成的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')
看起来脚本没有架构限定名称。如果在不同模式中有两个相同名称的约束,那么使用'OBJECT_ID(N'[YourSchema]。[DEF_Detail_IsDeleted]')会更安全。 – 2012-06-21 22:11:47
我用它来检查列和远程约束。它应该有你需要的一切。
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
[email protected]_TableName
AND [email protected]_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
最简单的方法来检查约束的存在(然后做一些事情,如果它存在,如拖放)是使用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函数的第二个参数被用于:
约束对象类型:
另外请注意,该架构是通常需要。约束模式通常采用父表的模式。
故障使用这种方法还可能会导致假阴性时,把你的约束(或任何你正在检查)括号 - (如),如果你的对象使用特殊字符,需要支架。
重要的是将参数中的模式名称添加到OBJECT_ID,如下所示:IF OBJECT_ID('dbo.CK_ConstraintName','C')不为NULL。没有指定模式,它会返回NULL。 – gator88 2014-04-14 10:07:28
嗨,谢谢你的回答,这真的很有帮助。只是想知道它是否适用于Oracle? – 2014-10-03 03:21:14
不适用于sql2000。只需使用OBJECTPROPERTY(OBJECT_ID('constraint_name'),'IsConstraint')= 1'从当前版本一直兼容到sql2000。不需要'dbo'模式。 – wqw 2017-07-12 13:33:40
我用下面的查询来检查现有约束之前,我创建它。
IF (NOT EXISTS(SELECT 1 FROM sysconstraints WHERE OBJECT_NAME(constid) = 'UX_CONSTRAINT_NAME' AND OBJECT_NAME(id) = 'TABLE_NAME')) BEGIN
...
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
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
如果有解释的话,这个答案会更有用,而不仅仅是倾销代码。 – 2014-10-28 17:57:32
第二@sphanley:你回答了一个已经收到好几个答案的老问题。请解释什么是更好或至少具体关于您的答案,以便它值得发布。 – honk 2014-10-28 18:11:13
你可以有一点需要注意使用上面的一个:
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]
因为一个表可以有多个外键,但仍不能有外键被检查
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
http://geekswithblogs.net/deadlydog/archive/2012/09/14/sql-server-script-commands-to-check-if-object-exists-and。aspx – gotqn 2013-04-12 07:10:38