Sql सर्वर में एक बाधा मौजूद है, तो कैसे जांचें?


269

मेरे पास यह एसक्यूएल है:

ALTER TABLE dbo.ChannelPlayerSkins
    DROP CONSTRAINT FK_ChannelPlayerSkins_Channels

लेकिन जाहिर है, कुछ अन्य डेटाबेस पर हम उपयोग करते हैं, बाधा का एक अलग नाम है। अगर नाम के साथ कोई बाधा है तो मैं कैसे जांच करूं FK_ChannelPlayerSkins_Channels



यहाँ कई उत्तर विफल हो जाते हैं जब एक ही बाधा नाम कई वस्तुओं पर या किसी अन्य स्कीमा में उपयोग किया जाता है।
मार्क शुल्त्स

जवाबों:


353

इसे इस्तेमाल करे:

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 सर्वर प्रबंधन स्टूडियो का उपयोग कर स्रोत कोड को देखने के लिए "ऑब्जेक्ट एक्सप्लोरर" में मिलता है। वहां से आप "मास्टर" डेटाबेस का विस्तार करते हैं, फिर "प्रोग्रामेबिलिटी", फिर "संग्रहीत प्रक्रियाएं", फिर "सिस्टम संग्रहीत प्रक्रियाएं" का विस्तार करते हैं। फिर आप "sys.sp_helpconstraint" ढूंढ सकते हैं और इसे राइट क्लिक करें और "संशोधित करें" चुनें। बस इसके लिए किसी भी बदलाव को नहीं बचाने के लिए सावधान रहें। इसके अलावा, आप किसी भी तालिका पर इस सिस्टम संग्रहीत कार्यविधि का उपयोग करके इसका उपयोग कर सकते हैं EXEC sp_helpconstraint YourTableNameHere


3
ध्यान देने वाली एक बात, बाधा को जोड़ने के लिए मेरी एसक्यूएल में, मैंने नाम के चारों ओर ब्रैकेट का उपयोग किया, जैसे [fk_Client_ProjectID_Project]। आपको WHERE क्लॉज में कोष्ठक को हटाना होगा।
स्कूबासेटेव

2
कोष्ठक में कुछ भी गलत नहीं है। यह एक SQL सर्वर प्रश्न है, एक MySQL नहीं।
अल्वारो गोंजालेज

1
यदि यह एक अद्वितीय बाधा है आप थोड़ा अलग संस्करण की आवश्यकता है: यदि नहीं मौजूद है (INFORMATION_SCHEMA.TABLE_CONSTRAINTS से 1 का चयन करें जहां CONSTRAINT_NAME = 'UNIQUE_Order_ExternalReferenceId') BEGIN ALTER तालिका आदेश जोड़ें बाधा UNIQUE_Order_ExternalReferenceId अद्वितीय (ExternalReferenceId) अंत
सांकेतिक शब्दों में बदलनेवाला

2
ऊपर एक अद्वितीय स्तंभ बाधा (SQL2008) के लिए काम नहीं किया। मुझे निम्नलिखित का उपयोग करना था: INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE यहां से CONSTRAINT_NAME = 'UC_constraintName' का चयन करें
एलन बी।

डिफ़ॉल्ट बाधाओं के लिए, केवल वैकल्पिक विधि सूचीबद्ध पंक्ति लौटाती है।
चार्जिंगपुन

247

एक बाधा के अस्तित्व की जाँच करने के लिए सबसे आसान तरीका (और फिर ऐसा कुछ करें जैसे कि अगर यह मौजूद है तो इसे छोड़ दें) 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 (बाधा या अकेले खड़े)
  • एफ = विदेश कुंजी बाधा
  • पीके = प्राथमिक कुंजी बाधा
  • R = नियम (पुरानी शैली, स्टैंड-अलोन)
  • UQ = UNIQUE बाधा

यह भी ध्यान दें कि स्कीमा की अक्सर आवश्यकता होती है। बाधाओं की स्कीमा आम तौर पर मूल तालिका का स्कीमा लेती है।

इस विधि का उपयोग करते समय अपने अवरोधों (या जो भी आप जाँच कर रहे हैं) को ब्रैकेट में रखने में विफलता भी एक झूठी नकारात्मक का कारण बन सकती है - यदि आपकी वस्तु असामान्य वर्ण (जैसे कि) का उपयोग करती है, तो ब्रैकेट की आवश्यकता होती है।


16
महत्वपूर्ण बात यह है कि पैरामीटर में OBJECT_ID में स्कीमा का नाम इस तरह जोड़ना है: IF OJJECT_ID ('dbo.CK_ConstraintName', 'C') IS NULL नहीं है। स्कीमा निर्दिष्ट किए बिना यह NULL देता है।
गेटोर 8

नमस्ते, आपके उत्तर के लिए धन्यवाद, यह वास्तव में उपयोगी है। बस सोच रहा था कि क्या यह ओरेकल के लिए लागू होता है?
एलन ज़िया

Sql2000 पर काम नहीं करता है। बस OBJECTPROPERTY(OBJECT_ID('constraint_name'), 'IsConstraint') = 1वर्तमान संस्करण से सभी sql2000 के लिए संगत होने का उपयोग करें। कोई dboस्कीमा भी आवश्यक नहीं है।
wqw

47

यदि आप अन्य प्रकार की बाधा की तलाश कर रहे हैं, उदाहरण के लिए चूक, तो आपको अलग-अलग क्वेरी का उपयोग करना चाहिए (से मैं INFORMATION_SCHEMA का उपयोग करके डिफ़ॉल्ट बाधा कैसे ढूंढ सकता हूं? Devio द्वारा उत्तर दिया गया है )। उपयोग:

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

नाम से एक डिफ़ॉल्ट बाधा खोजने के लिए।

मैंने अपनी पोस्ट " DDL ' में अलग-अलग' IF Not Exists" चेक को एक साथ रखा है, यदि SQL स्क्रिप्ट को फिर से चलाने योग्य बनाने के लिए "Exists नहीं है तो" शर्तें



19

क्या आप ऐसा कुछ देख रहे हैं, नीचे 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

बस कुछ देखना है ......

SQL Server 2008 R2 SSMS में, "स्क्रिप्ट बाधा के रूप में -> DROP और बनाएँ" कमांड नीचे 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 पंक्तियाँ देता है। (देखें माइक्रोसॉफ्ट कनेक्ट पोस्ट )।

डिफ़ॉल्ट बाधा का नाम गलत है, लेकिन मैं इसे इकट्ठा भी OBJECT_ID फ़ंक्शन के साथ कुछ करना है क्योंकि नाम बदलने से समस्या ठीक नहीं होती है।

इसे ठीक करने के लिए, मैंने OBJECT_ID का उपयोग हटा दिया और इसके बजाय डिफ़ॉल्ट बाधा नाम का उपयोग किया।

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

1
ऐसा लगता है कि स्क्रिप्ट स्कीमा नाम को योग्य नहीं बनाती है। OBJECT_ID(N'[YourSchema].[DEF_Detail_IsDeleted]')यदि आपके पास अलग-अलग स्कीमा में एक ही नाम की 2 बाधाएं हैं, तो उपयोग करना सुरक्षित होगा ।
मार्टिन स्मिथ

7

किसी मौजूदा बाधा के लिए जाँच करने से पहले मैं निम्नलिखित प्रश्न का उपयोग करता हूँ।

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

किसी दिए गए तालिका नाम को लक्षित करके बाधा के लिए यह प्रश्न। उम्मीद है की यह मदद करेगा।


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_SCHEMAआपका दोस्त है। इसमें सभी प्रकार के विचार हैं जो सभी प्रकार की स्कीमा जानकारी दिखाते हैं। अपने सिस्टम दृश्य देखें। आपको लगता है कि आपको बाधाओं से निपटने के तीन दृष्टिकोण हैं, एक होने के नाते CHECK_CONSTRAINTS


1

मैं एक स्तंभ पर और दूरस्थ बाधाओं की जांच करने के लिए इसका उपयोग करता हूं। इसमें वह सब कुछ होना चाहिए जो आपको चाहिए।

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
यदि डंपिंग कोड के बजाय इसके साथ कुछ स्पष्टीकरण थे, तो यह उत्तर अधिक उपयोगी होगा।
सैम हैनली

1
दूसरी @ शेंशली के लिए: आप एक पुराने प्रश्न का उत्तर देते हैं जिसमें पहले से ही कई अच्छे उत्तर हैं। कृपया बताएं कि यह आपके उत्तर के बारे में क्या बेहतर है या कम से कम विशिष्ट है ताकि यह पोस्ट करने लायक हो।
सम्मानित करें

0

आप एक केविएट के साथ ऊपर का उपयोग कर सकते हैं:

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]तालिका का उपयोग करने की आवश्यकता है क्योंकि कई विदेशी कुंजी हो सकती हैं और अभी भी विदेशी कुंजी की जांच नहीं की जा सकती है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.