बाधाओं को अस्थायी रूप से बंद करें (MS SQL)


208

मैं सभी DB बाधाओं (जैसे तालिका संबंधों) को अस्थायी रूप से बंद करने का एक रास्ता ढूंढ रहा हूं।

मुझे एक DB की तालिकाओं को दूसरे DB के लिए (INSERTs का उपयोग करके) कॉपी करना होगा। मुझे पता है कि मैं उचित क्रम में आदेशों को निष्पादित करके (रिश्तों को नहीं तोड़ने के लिए) प्राप्त कर सकता हूं।

लेकिन यह आसान होगा अगर मैं अस्थायी रूप से जांच की बाधाओं को बंद कर सकता हूं और ऑपरेशन खत्म होने के बाद इसे वापस चालू कर सकता हूं।

क्या यह संभव है?


3
यह पूरी कॉपी नहीं है मैं सिर्फ चयनित तालिकाओं को कॉपी करना चाहता हूं
Maciej

ऐसा करने के बारे में मेरी चिंता यह है कि यह न केवल आप सभी के लिए बाधाओं को दूर करता है। यदि आपको ऐसा करना चाहिए, तो डेटाबेस को पहले एकल उपयोगकर्ता मोड में डालें। अन्यथा आप डेटा अखंडता समस्याओं को समाप्त कर सकते हैं।
HLGEM

13
भविष्य के प्रिय लोग: आप डेटाबेस में सभी बाधाओं को एक बार में अक्षम और फिर से सक्षम कर सकते हैं; देखें stackoverflow.com/a/161410
ब्रिचिन्स

1
बाधाओं को सक्षम करने के लिए मत भूलना, जब किया!
माइक क्रिश्चियन

1
@ निकोलस बार्बुल्स्को मेला काफी; मैं sql-serverऔर sql-server-2005टैग से जा रहा था । मैंने जो लिंक दिया है वह SQL Server के लिए है, लेकिन आप Oracle में एक ही काम कर सकते हैं - यहाँ और यहाँ देखें । आप इसे PostgreSQL में भी कर सकते हैं ।
ब्रिचिन

जवाबों:


214

आप FK और CHECK बाधाओं को केवल SQL 2005+ में अक्षम कर सकते हैं । अन्य तालिका देखें

ALTER TABLE foo NOCHECK CONSTRAINT ALL

या

ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column

प्राथमिक कुंजी और अद्वितीय बाधाएं अक्षम नहीं की जा सकती हैं, लेकिन यह ठीक होना चाहिए, अगर मैंने आपको सही ढंग से समझा है।


10
लेकिन यह अस्थायी नहीं है।
निकोलस बारबुल्स्को

@ नाइकोलाब बार्बुल्स्को: यह निर्भर करता है। हाँ, यह है कि, आप उन्हें DROP / CREATE
gbn

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

यह सच नहीं है कि पीके और अद्वितीय बाधा को निष्क्रिय नहीं किया जा सकता है। कम से कम SQL सर्वर के हाल के संस्करण में यह काम करता है। उदाहरण के लिए, देखें: techonthenet.com/sql_server/primary_keys.php
Dejan

1
@NicolasBarbulesco Oracle पर? कुछ लेटेस्ट कुछ_टेबल को कास्ट करें // कुछ सामान करें जो बाधाओं का उल्लंघन करेगा, कुछ_टेबल को सक्षम करें और कुछ को नियंत्रित करें।
स्टीव स्विंसबर्ग

237
-- Disable the constraints on a table called tableName:
ALTER TABLE tableName NOCHECK CONSTRAINT ALL

-- Re-enable the constraints on a table called tableName:
ALTER TABLE tableName WITH CHECK CHECK CONSTRAINT ALL
---------------------------------------------------------

-- Disable constraints for all tables:
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

-- Re-enable constraints for all tables:
EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all'
---------------------------------------------------------

1
@kevinc नहीं। जब तक आप कंसीडर हो तब तक कोई फर्क नहीं पड़ता।
पो-टा-टू-

2
उद्धृत पहचानकर्ताओं का उपयोग करना मुझे विश्वास है कि ANSI मानक सेटिंग, जिसका अर्थ है कि आपको उन्हें स्ट्रिंग्स के लिए उपयोग नहीं करना चाहिए। सुसंगत होने से कोई लेना-देना नहीं है। देखें stackoverflow.com/questions/1992314/…
kevinc

1
प्रक्रिया के लिए धन्यवाद! और BTW यह सही आवरण है "sp_MSforeachtable" (एमएस अपरकेस)। धन्यवाद!
स्यालु

3
इसे सही उत्तर के रूप में चिह्नित किया जाना चाहिए क्योंकि यह पूरी तरह से प्रश्न का उत्तर देता है। केवल इतना ही नहीं, बल्कि @ डॉनल ने एक वाइल्डकार्ड संस्करण भी शामिल किया जो मेरे लिए बहुत मददगार था।
मैट जैक्सन

2
पुन: सक्षम करने के लिए धन्यवाद बिट। खासतौर पर वो डबल check checkजिसे कई लोग भूल जाते हैं !!
एलेक्स

57

और, यदि आप यह सत्यापित करना चाहते हैं कि आपने अपने रिश्तों को तोड़ दिया है और अनाथों को एक बार फिर से पेश किया है, तो आप अपने चेक को फिर से सशस्त्र करें, अर्थात

ALTER TABLE foo CHECK CONSTRAINT ALL

या

ALTER TABLE foo CHECK CONSTRAINT FK_something

तब आप किसी भी चेक किए गए कॉलम के विरुद्ध अपडेट कर सकते हैं और ऐसा कर सकते हैं:

UPDATE myUpdatedTable SET someCol = someCol, fkCol = fkCol, etc = etc

और उस बिंदु पर कोई भी त्रुटि बाधाओं को पूरा करने में विफलता के कारण होगी।


11
बेहतर तरीका यह है कि CHECK CHECK CONSTRAINT FK_something के साथ ALTER TABLE FOO
Cody Konior

1
ALTER TABLE Foo CHECK CONSTRAINT ALL या ALTER TABLE Foo CHECK CONSTRAINT FK_something बाधाओं को सक्षम करेगा लेकिन डेटा की जाँच किए बिना और इसका अर्थ है कि बाधा अविश्वासित (=_no_trusted = 1, is_disabled = 0) होगी।
बोगडान सहलेन १३'१

16

आप वास्तव में एकल SQL कमांड में सभी डेटाबेस बाधाओं को अक्षम कर सकते हैं और उन्हें एक और एकल कमांड को कॉल करने में फिर से सक्षम कर सकते हैं। देख:

मैं वर्तमान में SQL Server 2005 के साथ काम कर रहा हूं, लेकिन मुझे लगभग यकीन है कि इस दृष्टिकोण ने SQL 2000 के साथ भी काम किया है


0

सभी विदेशी कुंजी को अक्षम और सक्षम करना

CREATE PROCEDURE pr_Disable_Triggers_v2
    @disable BIT = 1
AS
    DECLARE @sql VARCHAR(500)
        ,   @tableName VARCHAR(128)
        ,   @tableSchema VARCHAR(128)

    -- List of all tables
    DECLARE triggerCursor CURSOR FOR
        SELECT  t.TABLE_NAME AS TableName
            ,   t.TABLE_SCHEMA AS TableSchema
        FROM    INFORMATION_SCHEMA.TABLES t
        ORDER BY t.TABLE_NAME, t.TABLE_SCHEMA

    OPEN    triggerCursor
    FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema
    WHILE ( @@FETCH_STATUS = 0 )
    BEGIN

        SET @sql = 'ALTER TABLE ' + @tableSchema + '.[' + @tableName + '] '
        IF @disable = 1
            SET @sql = @sql + ' DISABLE TRIGGER ALL'
        ELSE
            SET @sql = @sql + ' ENABLE TRIGGER ALL'

        PRINT 'Executing Statement - ' + @sql
        EXECUTE ( @sql )

        FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema

    END

    CLOSE triggerCursor
    DEALLOCATE triggerCursor

सबसे पहले, विदेशीकेयर्स कर्सर को सेलेक्ट स्टेटमेंट के रूप में घोषित किया जाता है जो विदेशी कुंजी और उनके टेबल नामों की सूची को इकट्ठा करता है। इसके बाद, कर्सर खोला जाता है और प्रारंभिक FETCH स्टेटमेंट निष्पादित किया जाता है। यह FETCH स्टेटमेंट पहली पंक्ति के डेटा को स्थानीय चर @foreignKeyName और @tableName में पढ़ेगा। जब एक कर्सर के माध्यम से लूपिंग करते हैं, तो आप 0 के मूल्य के लिए @@ FETCH_STATUS की जांच कर सकते हैं, जो इंगित करता है कि भ्रूण सफल था। इसका मतलब यह है कि लूप आगे बढ़ना जारी रखेगा इसलिए यह प्रत्येक क्रमिक विदेशी कुंजी को पंक्तियों से प्राप्त कर सकता है। @@ FETCH_STATUS कनेक्शन पर सभी कर्सर के लिए उपलब्ध है। इसलिए यदि आप कई कर्सर के माध्यम से लूप कर रहे हैं, तो FETCH स्टेटमेंट के तुरंत बाद स्टेटमेंट में @@ FETCH_STATUS का मान चेक करना महत्वपूर्ण है। @@ FETCH_STATUS कनेक्शन पर सबसे हाल के FETCH ऑपरेशन के लिए स्थिति को प्रतिबिंबित करेगा। @@ FETCH_STATUS के लिए मान्य मूल्य हैं:

0 = FETCH सफल रहा था
-1 = FETCH असफल रहा था
-2 - जिस पंक्ति को लाया गया था वह गायब है

लूप के अंदर, कोड अलग-अलग तरीके से ALTER TABLE कमांड बनाता है, जो इस बात पर निर्भर करता है कि इरादा विदेशी कुंजी बाधा को अक्षम करने या सक्षम करने के लिए है (CHECK या NOCHECK कीवर्ड का उपयोग करके)। फिर बयान को एक संदेश के रूप में मुद्रित किया जाता है ताकि इसकी प्रगति देखी जा सके और फिर कथन को निष्पादित किया जाए। अंत में, जब सभी पंक्तियों के माध्यम से पुनरावृत्त किया गया है, तो संग्रहीत कार्यविधि बंद हो जाती है और कर्सर को हटा देती है।

MSDN पत्रिका से अवरोध और ट्रिगर अक्षम करना देखें

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