我有這樣的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