2012-04-12 12 views
30

मेरे पास एक स्क्रिप्ट है जो एक संपूर्ण डेटाबेस बनाता है और कुछ दर्जन तालिकाओं में सभी रिकॉर्ड डालता है। यह बहुत अच्छा काम करता है, जब तक कि प्रसंस्करण के दौरान कोई समस्या न हो, और तालिका को प्रविष्टि के दौरान विफल होने पर IDENTITY_INSERT के साथ छोड़ दिया जाता है, और इससे पहले इसे फिर से बंद करने के लिए सेट किया जा सकता है।सभी तालिकाओं के लिए IDENTITY_INSERT OFF सेट करें

जब ऐसा होता है, तो स्क्रिप्ट स्वचालित रूप से फिर से चलाने का प्रयास करते समय विफल हो जाती है, त्रुटि के साथ "IDENTITY_INSERT पहले से ही तालिका xx के लिए चालू है" क्योंकि हम पहली तालिका के सम्मिलन में जाते हैं।

एक असफलता के रूप में मैं यह सुनिश्चित करना चाहता हूं कि सेटअप स्क्रिप्ट में शेष प्रोसेसिंग चलाने से पहले IDENTITY_INSERT सभी तालिकाओं के लिए बंद हो जाएगा।

एक विकल्प के रूप में, हम शायद एमएस एसक्यूएल कनेक्शन बंद कर सकते हैं और इसे फिर से खोल सकते हैं, जैसा कि मैं इसे समझता हूं, कनेक्शन सत्र के लिए सभी IDENTITY_INSERT मानों को साफ़ कर देगा।

ऐसा करने का सबसे अच्छा तरीका क्या है, और "पहले से ही" त्रुटियों को रोकें?

+0

SQL सर्वर का कौन सा संस्करण? –

+0

इस ऐप को w/2005 और ऊपर काम करने की ज़रूरत है, इसलिए आदर्श रूप से एक समाधान जो सभी हालिया और आगामी संस्करणों के लिए काम करता है। –

+0

नीचे मेरा समाधान 05 और बाद में काम करना चाहिए। –

उत्तर

18
EXEC sp_MSforeachtable @command1="SET IDENTITY_INSERT ? OFF" 
+3

मुझे यह बहुत पसंद है ... सिवाय इसके कि, इस डीबी में प्रत्येक तालिका में एक पहचान फ़ील्ड नहीं है, इसलिए यह विफल हो जाता है। अन्यथा मुझे संदेह है कि यह सही होगा। –

+1

किसी भी समय, सत्र में केवल एक तालिका में IDENTITY_INSERT प्रॉपर्टी http://technet.microsoft.com/en-us/library/aa259221(v=sql.80) के अनुसार चालू हो सकती है।एएसपीएक्स # फीडबैक – qub1n

+1

@ qub1n ओपी ने संपत्ति को चालू करने के लिए नहीं कहा था। –

36

गतिशील एसक्यूएल:

select 'set identity_insert ['+s.name+'].['+o.name+'] off' 
from sys.objects o 
inner join sys.schemas s on s.schema_id=o.schema_id 
where o.[type]='U' 
and exists(select 1 from sys.columns where object_id=o.object_id and is_identity=1) 

फिर & किसी अन्य क्वेरी विंडो में जिसके परिणामस्वरूप एसक्यूएल पेस्ट और चलाने

+0

इसे साझा करने के लिए आपको धन्यवाद, वैसे भी अच्छा चाल :) – ktutnik

+0

वाह, यह मेरे बेकन को बचाया। धन्यवाद! –

+0

मैं अपने कोड से अपने थोक डीबी डालने के लिए यह रखना चाहता हूं। क्या आप कुछ सुझाव दे सकते हैं कि जेपीए में इसे कैसे प्राप्त किया जाए? – muasif80

5
EXEC sp_MSforeachtable @command1="PRINT '?'; SET IDENTITY_INSERT ? OFF", 
@whereand = ' AND EXISTS (SELECT 1 FROM sys.columns WHERE object_id = o.id AND is_identity = 1)' 

लिन जवाब पर बिल्डिंग, मामले में आप के लिए बहुत आलसी हो कॉपी इसे एक से अधिक चरणों में करें - यह उन सभी तालिकाओं पर चलना चाहिए जहां पहचान कॉलम है।

चेतावनी केवल @ KevD के जवाब पर 2012 और sp_MSforeachtable पाठ्यक्रम पूरी तरह से असमर्थित की है में परीक्षण किया जाता है ...

+0

एसक्यूएल सर्वर 2014 और 2016 में भी काम करता है –

1

बिल्डिंग - यह अक्षम करने के लिए ठीक काम कर रहा था, लेकिन यहाँ भी सक्रिय करने के लिए और अधिक है।

सभी पहचान आवेषण जहां वे अक्षम करने की आवश्यकता को अक्षम करने के उपयोग -

EXEC sp_MSforeachtable @command1="PRINT '?'; SET IDENTITY_INSERT ? OFF", 
@whereand = ' AND EXISTS (SELECT 1 FROM sys.columns WHERE object_id = o.id 
AND is_identity = 1) and o.type = ''U''' 

सभी पहचान आवेषण जहां वे सक्षम करने की आवश्यकता को सक्षम करने के उपयोग -

EXEC sp_MSforeachtable @command1="PRINT '?'; SET IDENTITY_INSERT ? ON", 
@whereand = ' AND EXISTS (SELECT 1 FROM sys.columns WHERE object_id = o.id 
AND is_identity = 1) and o.type = ''U''' 

SQL सर्वर पर परीक्षण किया गया 2014 और 2016

0

मेरे पास एक समान समस्या थी लेकिन मैं उत्पादन में अनियंत्रित संग्रहीत प्रक्रियाओं का उपयोग नहीं करना चाहूंगा। इसे स्वचालित करने के लिए मैंने @ जॉन डेवी के उत्तर पर बनाया और इसे एक कर्सर में रखा। यह 407 एमएस में 69 9 टेबल से अधिक है।

DECLARE @sql NVARCHAR(500) -- SQL command to execute 

DECLARE sql_cursor CURSOR LOCAL FAST_FORWARD FOR 
SELECT 'SET identity_insert ['+s.name+'].['+o.name+'] OFF' 
FROM sys.objects o 
INNER JOIN sys.schemas s on s.schema_id=o.schema_id 
WHERE o.[type]='U' 
AND EXISTS(SELECT 1 FROM sys.columns WHERE object_id=o.object_id AND is_identity=1) 

OPEN sql_cursor 
FETCH NEXT FROM sql_cursor INTO @sql 

WHILE @@FETCH_STATUS = 0 
    BEGIN 
     EXECUTE sp_executesql @sql --> Comment this out to test 
     -- PRINT @sql --> Uncomment to test or if logging is desired 
     FETCH NEXT FROM sql_cursor INTO @sql 
    END 

CLOSE sql_cursor 
DEALLOCATE sql_cursor 

यदि आप कर्सर के खिलाफ हैं, तो इसे आसानी से थोड़ी देर में बदल दिया जा सकता है।

संबंधित मुद्दे