Bagaimana cara memeriksa apakah ada Kendala di server Sql?


271

Saya punya sql ini:

ALTER TABLE dbo.ChannelPlayerSkins
    DROP CONSTRAINT FK_ChannelPlayerSkins_Channels

tetapi ternyata, pada beberapa database lain yang kami gunakan, kendala memiliki nama yang berbeda. Bagaimana saya memeriksa apakah ada kendala dengan nama FK_ChannelPlayerSkins_Channels.



Banyak jawaban di sini gagal ketika nama kendala yang sama digunakan pada beberapa objek atau dalam skema lain.
Mark Schultheiss

Jawaban:


353

coba ini:

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

- EDIT -

Ketika saya awalnya menjawab pertanyaan ini, saya berpikir "Kunci Asing" karena pertanyaan asli bertanya tentang menemukan "FK_ChannelPlayerSkins_Channels". Sejak itu banyak orang berkomentar menemukan "kendala" lain di sini adalah beberapa pertanyaan lain untuk itu:

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

di sini adalah metode alternatif

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

Jika Anda memerlukan lebih banyak informasi kendala, lihat di dalam prosedur yang tersimpan sistem master.sys.sp_helpconstraintuntuk melihat bagaimana mendapatkan informasi tertentu. Untuk melihat kode sumber menggunakan SQL Server Management Studio masuk ke "Object Explorer". Dari sana Anda perluas database "Master", kemudian perluas "Programmability", lalu "Stored Procedures", lalu "System Stored Procedures". Anda kemudian dapat menemukan "sys.sp_helpconstraint" dan klik kanan dan pilih "modifikasi". Berhati-hatilah untuk tidak menyimpan perubahan apa pun padanya. Juga, Anda bisa menggunakan prosedur yang tersimpan sistem ini di tabel mana saja dengan menggunakannya EXEC sp_helpconstraint YourTableNameHere.


3
Satu hal yang perlu diperhatikan, dalam SQL saya untuk menambahkan batasan, saya menggunakan tanda kurung di sekitar nama seperti, [fk_Client_ProjectID_Project]. Anda HARUS menghapus tanda kurung di klausa WHERE.
ScubaSteve

2
Tidak ada yang salah dalam tanda kurung. Ini adalah pertanyaan SQL Server, bukan pertanyaan MySQL.
Álvaro González

1
Jika itu Kendala Unik Anda membutuhkan versi yang sedikit berbeda: JIKA TIDAK ada (SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS mana CONSTRAINT_NAME = 'UNIQUE_Order_ExternalReferenceId') BEGIN ALTER TABLE Orde Masukkan CONSTRAINT UNIQUE_Order_ExternalReferenceId UNIK (ExternalReferenceId) END
The Coder

2
Di atas tidak berfungsi untuk kendala kolom unik (SQL2008). Saya harus menggunakan yang berikut ini: SELECT * FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE WHERE CONSTRAINT_NAME = 'UC_constraintName'
Alan B. Dee

Untuk kendala default, hanya metode alternatif yang tercantum mengembalikan satu baris.
ChargingPun

249

Cara termudah untuk memeriksa keberadaan kendala (dan kemudian melakukan sesuatu seperti menjatuhkannya jika ada) adalah dengan menggunakan fungsi OBJECT_ID () ...

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

OBJECT_ID dapat digunakan tanpa parameter kedua ('C' untuk kendala pemeriksaan saja) dan itu juga bisa berfungsi, tetapi jika nama kendala Anda cocok dengan nama objek lain dalam database Anda mungkin mendapatkan hasil yang tidak terduga.

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

OBJECT_ID juga dapat digunakan dengan "batasan" lain seperti batasan Kunci Asing atau batasan Kunci Utama, dll. Untuk hasil terbaik, selalu sertakan jenis objek yang sesuai sebagai parameter kedua untuk fungsi OBJECT_ID:

Jenis Objek Kendala:

  • C = PERIKSA kendala
  • D = DEFAULT (kendala atau berdiri sendiri)
  • F = Kendala KUNCI ASING
  • PK = Kendala KUNCI UTAMA
  • R = Aturan (gaya lama, berdiri sendiri)
  • UQ = Batasan UNIK

Juga perhatikan bahwa skema sering diperlukan. Skema kendala umumnya menggunakan skema tabel induk.

Kegagalan untuk menempatkan kendala Anda (atau apa pun yang Anda periksa) dalam tanda kurung saat menggunakan metode ini juga dapat menyebabkan negatif palsu - jika objek Anda menggunakan karakter yang tidak biasa (seperti a.), Tanda kurung diperlukan.


16
Yang penting adalah menambahkan nama skema dalam parameter ke OBJECT_ID seperti ini: JIKA OBJECT_ID ('dbo.CK_ConstraintName', 'C') BUKAN NULL. Tanpa menentukan skema, ia mengembalikan NULL.
gator88

Hai, terima kasih atas jawaban Anda, ini sangat membantu. Hanya ingin tahu apakah itu berlaku untuk Oracle?
Allen Xia

Tidak berfungsi di sql2000. Cukup gunakan OBJECTPROPERTY(OBJECT_ID('constraint_name'), 'IsConstraint') = 1agar kompatibel dari versi saat ini hingga sql2000. Tidak dbodiperlukan skema juga.
wqw



19

Apakah Anda melihat sesuatu seperti ini, di bawah ini diuji dalam 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]')

10

Hanya sesuatu yang harus diwaspadai ......

Dalam SQL Server 2008 R2 SSMS, perintah "Script Constraint as -> DROP And CREATE To" menghasilkan T-SQL seperti di bawah ini

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

Di luar kotak, skrip ini TIDAK menjatuhkan batasan karena SELECT mengembalikan 0 baris. (lihat posting Microsoft Connect ).

Nama batasan default salah tetapi saya kumpulkan juga ada hubungannya dengan fungsi OBJECT_ID karena mengubah nama tidak memperbaiki masalah.

Untuk memperbaikinya, saya menghapus penggunaan OBJECT_ID dan menggunakan nama kendala default sebagai gantinya.

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

1
Sepertinya skrip tidak memenuhi kualifikasi nama. Akan lebih aman untuk digunakan OBJECT_ID(N'[YourSchema].[DEF_Detail_IsDeleted]')jika Anda memiliki 2 kendala dengan nama yang sama di skema yang berbeda.
Martin Smith

7

Saya menggunakan kueri berikut untuk memeriksa kendala yang ada sebelum saya membuatnya.

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

Ini kueri untuk kendala dengan nama yang menargetkan nama tabel yang diberikan. Semoga ini membantu.


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_SCHEMAadalah temanmu Ini memiliki semua jenis pandangan yang menunjukkan semua jenis informasi skema. Periksa tampilan sistem Anda. Anda akan menemukan Anda memiliki tiga pandangan berurusan dengan kendala, satu makhluk CHECK_CONSTRAINTS.


1

Saya menggunakan ini untuk memeriksa dan remote kendala pada kolom. Itu harus memiliki semua yang Anda butuhkan.

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
Jawaban ini akan lebih bermanfaat jika ada beberapa penjelasan yang menyertainya, daripada hanya membuang kode.
Sam Hanley

1
Ke @sphanley kedua: Anda menjawab pertanyaan lama yang sudah memiliki beberapa jawaban yang diterima dengan baik. Tolong jelaskan apa yang lebih baik atau paling tidak spesifik tentang jawaban Anda sehingga layak dikirim.
membunyikan

0

Anda dapat menggunakan yang di atas dengan satu peringatan:

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 

Harus menggunakan name = [Constraint name]karena tabel mungkin memiliki beberapa kunci asing dan masih belum kunci asing diperiksa

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.