Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

सभी विदेशी कुंजी बाधाओं को अस्थायी रूप से अक्षम करें

विदेशी कुंजी बाधाओं को अक्षम करने के लिए:

DECLARE @sql NVARCHAR(MAX) = N'';

;WITH x AS 
(
  SELECT DISTINCT obj = 
      QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' 
    + QUOTENAME(OBJECT_NAME(parent_object_id)) 
  FROM sys.foreign_keys
)
SELECT @sql += N'ALTER TABLE ' + obj + ' NOCHECK CONSTRAINT ALL;
' FROM x;

EXEC sp_executesql @sql;

पुन:सक्षम करने के लिए:

DECLARE @sql NVARCHAR(MAX) = N'';

;WITH x AS 
(
  SELECT DISTINCT obj = 
      QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' 
    + QUOTENAME(OBJECT_NAME(parent_object_id)) 
  FROM sys.foreign_keys
)
SELECT @sql += N'ALTER TABLE ' + obj + ' WITH CHECK CHECK CONSTRAINT ALL;
' FROM x;

EXEC sp_executesql @sql;

हालांकि, आप छंटनी . नहीं कर पाएंगे तालिकाओं, आपको उनमें से सही क्रम में हटाना होगा। अगर आपको काटना . करना है उन्हें, आपको बाधाओं को पूरी तरह से छोड़ने और उन्हें फिर से बनाने की आवश्यकता है। यह करना आसान है यदि आपकी विदेशी कुंजी बाधाएं सभी सरल, एकल-स्तंभ बाधाएं हैं, लेकिन निश्चित रूप से अधिक जटिल हैं यदि इसमें कई कॉलम शामिल हैं।

यहां कुछ ऐसा है जिसे आप आजमा सकते हैं। इसे अपने एसएसआईएस पैकेज का एक हिस्सा बनाने के लिए आपको एसएसआईएस पैकेज चलने के दौरान एफके परिभाषाओं को स्टोर करने के लिए एक जगह की आवश्यकता होगी (आप यह सब एक स्क्रिप्ट में नहीं कर पाएंगे)। तो कुछ उपयोगिता डेटाबेस में, एक टेबल बनाएं:

CREATE TABLE dbo.PostCommand(cmd NVARCHAR(MAX));

फिर आपके डेटाबेस में, आपके पास एक संग्रहीत कार्यविधि हो सकती है जो ऐसा करती है:

DELETE other_database.dbo.PostCommand;

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fk.parent_object_id))
   + '.' + QUOTENAME(OBJECT_NAME(fk.parent_object_id)) 
   + ' ADD CONSTRAINT ' + fk.name + ' FOREIGN KEY (' 
   + STUFF((SELECT ',' + c.name
    FROM sys.columns AS c 
        INNER JOIN sys.foreign_key_columns AS fkc 
        ON fkc.parent_column_id = c.column_id
        AND fkc.parent_object_id = c.[object_id]
    WHERE fkc.constraint_object_id = fk.[object_id]
    ORDER BY fkc.constraint_column_id 
    FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '')
+ ') REFERENCES ' + 
QUOTENAME(OBJECT_SCHEMA_NAME(fk.referenced_object_id))
+ '.' + QUOTENAME(OBJECT_NAME(fk.referenced_object_id))
+ '(' + 
STUFF((SELECT ',' + c.name
    FROM sys.columns AS c 
        INNER JOIN sys.foreign_key_columns AS fkc 
        ON fkc.referenced_column_id = c.column_id
        AND fkc.referenced_object_id = c.[object_id]
    WHERE fkc.constraint_object_id = fk.[object_id]
    ORDER BY fkc.constraint_column_id 
    FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '') + ');
' FROM sys.foreign_keys AS fk
WHERE OBJECTPROPERTY(parent_object_id, 'IsMsShipped') = 0;

INSERT other_database.dbo.PostCommand(cmd) SELECT @sql;

IF @@ROWCOUNT = 1
BEGIN
  SET @sql = N'';

  SELECT @sql += N'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fk.parent_object_id))
    + '.' + QUOTENAME(OBJECT_NAME(fk.parent_object_id)) 
    + ' DROP CONSTRAINT ' + fk.name + ';
  ' FROM sys.foreign_keys AS fk;

  EXEC sp_executesql @sql;
END

अब जब आपका एसएसआईएस पैकेज समाप्त हो गया है, तो उसे एक अलग संग्रहित प्रक्रिया को कॉल करना चाहिए, जो करता है:

DECLARE @sql NVARCHAR(MAX);

SELECT @sql = cmd FROM other_database.dbo.PostCommand;

EXEC sp_executesql @sql;

यदि आप यह सब केवल डिलीट करने के बजाय काट-छाँट करने में सक्षम होने के लिए कर रहे हैं, तो मेरा सुझाव है कि बस हिट लें और डिलीट चलाएँ। शायद लॉग के प्रभाव को कम करने के लिए बल्क-लॉग किए गए पुनर्प्राप्ति मॉडल का उपयोग करें। सामान्य तौर पर मैं यह नहीं देखता कि यह समाधान सही क्रम में केवल डिलीट का उपयोग करने की तुलना में कितना तेज होगा।

2014 में मैंने इसके बारे में एक और विस्तृत पोस्ट यहाँ प्रकाशित की:

  • SQL सर्वर में सभी विदेशी कुंजी बाधाओं को छोड़ें और फिर से बनाएं


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SSMS संस्करण 18 - कोई डेटाबेस आरेख नहीं

  2. SQL सर्वर अस्थायी वस्तु कैशिंग

  3. SQL सर्वर में @@ SERVICENAME क्या है?

  4. मैं टीएसक्यूएल का उपयोग कर डेटाबेस में सभी तालिकाओं की सूची कैसे प्राप्त करूं?

  5. SQL सर्वर कर्सर प्रकार - केवल फॉरवर्ड डायनेमिक कर्सर | SQL सर्वर ट्यूटोरियल / TSQL ट्यूटोरियल