Sql sunucusunda bir kısıtlama olup olmadığını nasıl kontrol edebilirim?


270

Bu sql var:

ALTER TABLE dbo.ChannelPlayerSkins
    DROP CONSTRAINT FK_ChannelPlayerSkins_Channels

ancak görünüşe göre, kullandığımız bazı diğer veritabanlarında, kısıtlamanın farklı bir adı var. Adla ilgili bir kısıtlama olup olmadığını nasıl kontrol ederim FK_ChannelPlayerSkins_Channels.



Buradaki yanıtların çoğu, aynı kısıtlama adı birden çok nesnede veya başka bir şemada kullanıldığında başarısız olur.
Mark Schultheiss

Yanıtlar:


353

bunu dene:

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

-- DÜZENLE --

Bu soruyu ilk olarak yanıtladığımda, "Yabancı Anahtar" diye düşünüyordum çünkü asıl soru "FK_ChannelPlayerSkins_Channels" bulmayı sordu. O zamandan beri birçok kişi diğer "kısıtlamaları" bulma konusunda yorumlarda bulundu:

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

İşte alternatif bir yöntem

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

Daha fazla kısıtlama bilgisine ihtiyacınız varsa, master.sys.sp_helpconstraintbelirli bilgileri nasıl alacağınızı görmek için sistem saklı yordamının içine bakın. SQL Server Management Studio'yu kullanarak kaynak kodunu görüntülemek için "Nesne Gezgini" ne girin. Buradan "Ana" veritabanını, ardından "Programlanabilirlik" i, ardından "Saklı Yordamlar" ı ve ardından "Sistem Saklı Yordamları" nı genişletin. Daha sonra "sys.sp_helpconstraint" dosyasını bulup sağ tıklayıp "değiştir" i seçebilirsiniz. Sadece herhangi bir değişiklik kaydetmemeye dikkat edin. Ayrıca, bu sistem saklı yordamını herhangi bir tablodaki gibi kullanarak kullanabilirsiniz EXEC sp_helpconstraint YourTableNameHere.


3
Dikkat edilmesi gereken bir şey, benim SQL'de kısıtlama eklemek için, [fk_Client_ProjectID_Project] gibi ad etrafında parantez kullandım. WHERE yan tümcesindeki braketleri ÇIKARMALISINIZ.
ScubaSteve

2
Parantez içinde yanlış bir şey yok. Bu bir SQL Server sorusudur, MySQL sorusudur.
Álvaro González

1
Bir Benzersiz Kısıtlama ise biraz daha farklı bir sürümü gerekir: NOT VARSA (INFORMATION_SCHEMA.TABLE_CONSTRAINTS GELEN 1 SEÇ nerede kısıt_ismi = 'UNIQUE_Order_ExternalReferenceId') ALTER tablo al ADD CONSTRAıNT'I UNIQUE_Order_ExternalReferenceId EŞSİZ (ExternalReferenceId) END BEGIN
Coder

2
Yukarıdakiler benzersiz bir sütun kısıtlaması (SQL2008) için çalışmadı. Aşağıdakileri kullanmak zorunda kaldım: SELECT * FROM Information_SCHEMA.CONSTRAINT_COLUMN_USAGE NEREDE CONSTRAINT_NAME = 'UC_constraintName'
Alan B. Dee

Varsayılan kısıtlamalar için, yalnızca listelenen alternatif yöntem bir satır döndürür.
ChargingPun

248

Bir kısıtlamanın varlığını kontrol etmenin en kolay yolu (ve eğer varsa, bırakmak gibi bir şey yapmak) OBJECT_ID () işlevini kullanmaktır ...

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

OBJECT_ID, ikinci parametre olmadan kullanılabilir (yalnızca kontrol kısıtlamaları için 'C') ve bu da işe yarayabilir, ancak kısıtlama adınız veritabanındaki diğer nesnelerin adıyla eşleşirse beklenmedik sonuçlar alabilirsiniz.

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

OBJECT_ID, Yabancı Anahtar kısıtlamaları veya Birincil Anahtar kısıtlamaları vb. Gibi diğer "kısıtlamalarla" da kullanılabilir. En iyi sonuçlar için, her zaman OBJECT_ID işlevi için ikinci parametre olarak uygun nesne türünü ekleyin:

Kısıtlama Nesne Türleri:

  • C = CHECK kısıtlaması
  • D = VARSAYILAN (kısıtlama veya bağımsız)
  • F = FOREIGN KEY kısıtlaması
  • PK = PRIMARY KEY kısıtlaması
  • R = Kural (eski tarz, bağımsız)
  • UQ = UNIQUE kısıtlaması

Şemanın sıklıkla gerekli olduğunu da unutmayın. Kısıtlamaların şeması genellikle üst tablonun şemasını alır.

Bu yöntemi kullanırken kısıtlamalarınızı (veya denetlediğiniz her şeyi) parantez içine koymamak da yanlış bir negatife neden olabilir - nesneniz olağandışı karakterler (a. Gibi) kullanıyorsa, parantez gereklidir.


16
Önemli olan, şema adını OBJECT_ID parametresine şu şekilde eklemektir: IF OBJECT_ID ('dbo.CK_ConstraintName', 'C') NULL DEĞİLDİR. Şema belirtmeden NULL döndürür.
gator88

Merhaba, Cevabınız için teşekkürler, gerçekten yararlı. Oracle için geçerli olup olmadığını mı merak ediyorsunuz?
Allen Xia

Sql2000 üzerinde çalışmaz. Sadece kullanmak OBJECTPROPERTY(OBJECT_ID('constraint_name'), 'IsConstraint') = 1akım bütün sürümü SQL2000 yolunda gelen uyumlu olacak şekilde. Hiçbir dboşema çok gerekli.
wqw

47

Eğer kısıtlama diğer tipi, örn varsayılan arıyorsanız, siz (Dan farklı bir sorgu kullanmalıdır Ben INFORMATION_SCHEMA kullanarak varsayılan kısıtlama? Bulurum nasıl tarafından cevap devio ). kullanın:

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

ada göre varsayılan bir kısıtlama bulmak için.

SQL komut dosyalarını yeniden çalıştırılabilir hale getirmek için " DDL" Varsa "koşullarını farklı" Varsa "denetimlerini bir araya getirdim "



19

Böyle bir şeye mi bakıyorsunuz, aşağıda SQL Server 2005'te test edilmiştir

SELECT * FROM sys.check_constraints WHERE 
object_id = OBJECT_ID(N'[dbo].[CK_accounts]') AND 
parent_object_id = OBJECT_ID(N'[dbo]. [accounts]')

10

Dikkat edilmesi gereken bir şey ...

SQL Server 2008 R2 SSMS'de, "Script Constraint as -> DROP And CREATE To" komutu aşağıdaki gibi T-SQL üretir

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

Kutunun dışında, bu komut dosyası SELECT 0 satır döndürdüğü için kısıtlamayı DÜŞÜRMİYOR. ( Microsoft Connect yayınına bakın ).

Varsayılan kısıtlamanın adı yanlış ama adının değiştirilmesi sorunu çözmediği için OBJECT_ID işleviyle de ilgisi var.

Bunu düzeltmek için OBJECT_ID kullanımını kaldırdım ve bunun yerine varsayılan kısıtlama adını kullandım.

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

1
Betiğin şema adı nitelendirmediği anlaşılıyor. OBJECT_ID(N'[YourSchema].[DEF_Detail_IsDeleted]')Farklı şemalarda aynı adda 2 kısıtlamanız olması durumunda kullanmak daha güvenli olacaktır .
Martin Smith

7

Ben oluşturmadan önce varolan bir kısıtlama kontrol etmek için aşağıdaki sorguyu kullanın.

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

Bu, belirli bir tablo adını hedefleyen ada göre kısıtlamayı sorgular. Bu yardımcı olur umarım.


3
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 

3
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

2

INFORMATION_SCHEMAsenin arkadaşın. Her türlü şema bilgisini gösteren her türlü görüşe sahiptir. Sistem görünümlerinizi kontrol edin. Biri olmak üzere, kısıtlamalarla ilgili üç görüşünüz olduğunu göreceksiniz CHECK_CONSTRAINTS.


1

Bunu bir sütundaki kısıtlamaları kontrol etmek ve uzaktan kontrol etmek için kullanıyorum. İhtiyacınız olan her şeye sahip olmalı.

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

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                

1
Bu cevap, sadece kod dökümü yerine, onunla birlikte bazı açıklamalar olsa daha yararlı olacaktır.
Sam Hanley

1
İkinci olarak @sphanley: Çoktan iyi cevap almış eski bir soruyu cevaplıyorsunuz. Cevabınız için neyin daha iyi veya en azından spesifik olduğunu açıklayın, böylece göndermeye değer.
honk

0

Yukarıdaki olanı bir uyarı ile kullanabilirsiniz:

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 

İhtiyaç kullanmak name = [Constraint name]bir tablo birden yabancı tuşları var ve hala yabancı anahtar için denetleniyor olmayabilir çünkü

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.