अन्य SQL2008 डेटाबेस (इंडेक्स, ट्रिगर्स, आदि सहित) के लिए टेबल ले जाना


16

मुझे एक SQL2008 डेटाबेस से दूसरे में बड़े (लाखों पंक्तियों) तालिकाओं का एक पूरा गुच्छा (100+) स्थानांतरित करने की आवश्यकता है।

मैंने मूल रूप से केवल आयात / निर्यात विज़ार्ड का उपयोग किया था, लेकिन सभी गंतव्य तालिकाओं में प्राथमिक और विदेशी कुंजियाँ, अनुक्रमणिका, बाधाएँ, ट्रिगर आदि गायब थे (पहचान कॉलम भी सादे INT में बदल दिए गए थे, लेकिन मुझे लगता है कि मैंने अभी-अभी एक चेकबॉक्स को याद किया था। जादूगर।)

ऐसा करने का सही तरीका क्या है?

यदि यह सिर्फ एक-दो टेबल थे, तो मैं स्रोत पर वापस जाऊंगा, टेबल डेफिनिशन (सभी इंडेक्स, आदि के साथ) स्क्रिप्ट बाहर करूंगा, फिर गंतव्य पर स्क्रिप्ट के इंडेक्स निर्माण भाग को चलाऊंगा। लेकिन कई तालिकाओं के साथ, यह अव्यवहारिक लगता है।

यदि बहुत अधिक डेटा नहीं था, तो मैं डेटा सहित स्रोत को स्क्रिप्ट करने के लिए "क्रिएट स्क्रिप्ट्स ..." विज़ार्ड का उपयोग कर सकता हूं, लेकिन 72 मीटर की पंक्ति स्क्रिप्ट सिर्फ एक अच्छे विचार की तरह प्रतीत नहीं होती है!


और यह डेटाबेस में सभी तालिकाओं नहीं है?
thursdaysgeek

@thursdaysgeek: इसके लगभग सभी टेबल हैं, लेकिन गंतव्य डेटाबेस में 100+ टेबल पहले से हैं। तो बस एक अलग नाम के साथ बैकअप से बहाल करना एक विकल्प नहीं है। इसे मूल रूप से "इन दो बड़े डेटाबेस को एक साथ मर्ज करें" के रूप में सोचें।
ब्रैडक

जवाबों:


14

तालिकाओं को स्क्रिप्ट करना, फिर डेटा स्थानांतरित करने के लिए SSIS का उपयोग करना नए डेटाबेस में डेटा स्थानांतरित करने का सबसे विश्वसनीय और प्रभावी तरीका होगा।


9

हमने वास्तव में इसे आयात विज़ार्ड के साथ मिलकर बहुत सारी स्क्रिप्टिंग स्क्रिप्टिंग का उपयोग किया था, लेकिन आज सुबह मुझे एक बेहतर जवाब मिला, टिबोर काराज़ी के ब्लॉग लेख के सौजन्य से ।

यहां हमारी हताशा का एक हिस्सा यह था कि SQL 2000 "डीटीएस आयात / निर्यात विज़ार्ड" वास्तव में "कॉपी ऑब्जेक्ट्स और डेटा" का चयन करके इसे लगभग तुच्छ आसान बनाता है:

DTS आयात विज़ार्ड

यह तीसरा विकल्प वह है जिसमें अनुक्रमणिका / ट्रिगर आदि को शामिल करने की क्षमता है:

उन्नत विकल्प

यह विकल्प SQL 2005/2008 आयात विज़ार्ड से हटा दिया गया था । क्यों? कोई जानकारी नहीं:

2008 आयात जादूगर

2005/2008 में, आपको जाहिरा तौर पर BIDS में SSIS पैकेज को मैन्युअल रूप से बनाना होगा और ट्रांसफ़र SQL सर्वर ऑब्जेक्ट्स टास्क का उपयोग करना होगा , जिसमें सभी समान विकल्प हैं जो 2000 विज़ार्ड में थे:

SSIS स्थानांतरण SQL सर्वर ऑब्जेक्ट टास्क


बस यह पोस्ट करना चाहता था कि मैंने इस SSIS विधि का उपयोग इसी तरह के अन्य कार्य के लिए किया, और इसने बहुत अच्छा काम किया!
ब्राडकास्ट

8

मैं लक्ष्य डेटाबेस में तालिकाओं को उत्पन्न करने के लिए टेबल की स्क्रिप्टिंग पर विचार करूंगा, या तुलना उपकरण (जैसे रेड गेट) का उपयोग करूंगा। सूचकांक या बाधाओं के बिना अभी तक।

तब मैं एक ही सर्वर पर एक अलग नाम के साथ डेटाबेस को पुनर्स्थापित करने और विचार कर रहा हूं

 INSERT newdb.dbo.newtable SELECT * FROM olddb.dbo.oldtable

.. प्रत्येक तालिका के लिए, यदि आवश्यक हो तो सेट IDSERT INSERT के साथ

फिर मैं डेटा लोड करने के बाद अनुक्रमित और बाधाओं को जोड़ूंगा।

यह आपके आराम स्तर पर SSIS (mrdenny's answer) या यदि आप कच्ची SQL पसंद करते हैं, पर निर्भर करता है।


6

मैं श्री डेनी के उत्तर में जोड़ना चाहूंगा: टेबल स्कीमा को स्क्रिप्ट से बाहर करना होगा फिर डेटा को स्थानांतरित करने के लिए बीसीपी का उपयोग करना चाहिए। यदि आप SSIS से परिचित नहीं हैं, तो BCP और बैचों का उपयोग करना आसान होना चाहिए। लाखों पंक्तियों के लिए बीसीपी (बल्क इंसर्ट) को कुछ नहीं धड़कता है :)।


4

मैं वह हूं जो एसएसआईएस से पूरी तरह असहज है।

जब स्रोत तालिकाओं में कोई पहचान कॉलम नहीं होता है

  1. लक्ष्य सर्वर पर एक खाली डेटाबेस बनाएँ
  2. लक्ष्य सर्वर पर स्रोत सर्वर से लिंक सर्वर बनाएँ
  3. स्रोत डेटाबेस पर नीचे स्क्रिप्ट चलाने के लिए चयन * बयान ... में उत्पन्न करने के लिए
  4. लक्ष्य डेटाबेस से उत्पन्न स्क्रिप्ट चलाएँ
  5. स्रोत डेटाबेस से स्क्रिप्ट प्राथमिक कुंजी, अनुक्रमित, ट्रिगर, फ़ंक्शन और प्रक्रियाएं
  6. उत्पन्न लिपि द्वारा इन वस्तुओं को बनाएँ

अब टी-एसक्यूएल को सेलेक्ट * स्टेटमेंट ... में जेनरेट करना है

SET NOCOUNT ON

declare @name sysname
declare @sql varchar(255)

declare db_cursor cursor for
select name from sys.tables order by 1
open db_cursor

fetch next from db_cursor into @name
while @@FETCH_STATUS = 0
begin
    Set @sql = 'select * into [' + @name + '] from [linked_server].[source_db].[dbo].[' + @name + '];'
    print @sql

    fetch next from db_cursor into @name
end

close db_cursor
deallocate db_cursor

यह कॉपी करने के लिए प्रत्येक तालिका के लिए एक लाइन बनाता है

select * into [Table1] from [linked_server].[source_db].[dbo].[Table1];

मामले में कि तालिकाओं में पहचान कॉलम होते हैं, मैं पहचान की संपत्ति और प्राथमिक कुंजी सहित तालिकाओं को स्क्रिप्ट करता हूं।

मैं डालने का उपयोग नहीं करता ... चयन करें ... इस मामले में एक लिंक किए गए सर्वर का उपयोग कर रहा है, क्योंकि यह कोई थोक तकनीक नहीं है। मैं कुछ PowerShell स्क्रिप्ट्स पर काम कर रहा हूं, जो [इस SO प्रश्न 1 के समान हैं , लेकिन मैं अभी भी एरर हैंडलिंग पर काम कर रहा हूं। वास्तव में बड़ी तालिकाएं मेमोरी त्रुटियों से बाहर निकल सकती हैं, क्योंकि डेटाबेस में SQLBulkCopy के माध्यम से भेजने से पहले एक पूरी तालिका को मेमोरी में लोड किया जाता है।

अनुक्रमणिका आदि का मनोरंजन ऊपर के मामले के समान है। इस बार मैं प्राथमिक कुंजी के मनोरंजन को छोड़ सकता हूं।


यदि तालिकाओं में पहचान कॉलम हैं, तो आप इस प्रश्न को पसंद कर सकते हैं । यह आपको कुछ मैनुअल काम से बचाएगा। मैं अभी भी बल्क इंसर्ट बैच / SSIS को प्राथमिकता देता हूं, हो सकता है कि एक विस्तृत नेटवर्क पर लिंक्ड सर्वर एक अच्छा समाधान न हो।
मैरियन

1
@Marian कृपया पर एक नज़र डालें dba.stackexchange.com/questions/297/... यदि आप लघु उद्योगों को बढ़ावा देना चाहते। मैंने SSIS की कोशिश नहीं की, लेकिन आयात निर्यात विज़ार्ड (लिंक सर्वर के अलावा) भी विफल रहा।
bernd_k

मैंने खुशी के साथ मदद की होगी, लेकिन मेरे पास कोई ओरेकल बॉक्स उपलब्ध नहीं है। वैसे भी, मैं जो पढ़ने में कामयाब रहा हूं, वहाँ कोई प्रदाता नहीं हैं जो Oracle CLOB का समर्थन करेंगे ..
Marian

मैं इस पर आपके साथ हूं - मैं कभी-कभी माइग्रेट डेटा करता हूं, लेकिन एसएसआईएस का उपयोग कभी नहीं करता।
एके

2

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

फिर, नए के साथ मूल डेटाबेस से डेटा को सिंक्रनाइज़ करें (सभी तालिकाएं हैं, लेकिन वे सभी खाली हैं) तालिकाओं में रिकॉर्ड सम्मिलित करने के लिए

मैं इसके लिए ApexSQL Diff और ApexSQL Data Diff का उपयोग करता हूँ , लेकिन अन्य समान उपकरण हैं।

इस प्रक्रिया के बारे में अच्छी बात यह है कि आपको वास्तव में उपकरण का उपयोग करने वाले डेटाबेस को सिंक्रनाइज़ करने की आवश्यकता नहीं है, क्योंकि यह लाखों पंक्तियों के लिए काफी दर्दनाक हो सकता है।

आप बस एक INSERT INTO SQL स्क्रिप्ट बना सकते हैं (अगर यह कई गिग्स है तो आश्चर्यचकित न हों) और इसे निष्पादित करें।

चूंकि एसक्यूएल सर्वर मैनेजमेंट स्टूडियो में इतनी बड़ी स्क्रिप्ट्स भी नहीं खोली जा सकतीं, मैं sqlcmd या osql का उपयोग करता हूं


1

जैसा कि @ मद्देनी ने उल्लेख किया है -

  1. सभी इंडेक्स, एफके, आदि के साथ पहले टेबल बाहर स्क्रिप्ट करें और गंतव्य डेटाबेस में खाली टेबल बनाएं।

SSIS का उपयोग करने के बजाय, डेटा डालने के लिए BCP का उपयोग करें

  1. नीचे स्क्रिप्ट का उपयोग करके डेटा को bcp करें। SSMS को टेक्स्ट मोड में सेट करें और एक बैट फाइल में स्क्रिप्ट के नीचे उत्पन्न आउटपुट को कॉपी करें।

    -- save below output in a bat file by executing below in SSMS in TEXT mode
    
    -- clean up: create a bat file with this command --> del D:\BCP\*.dat 
    
    select '"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe" ' /* path to BCP.exe */
        +  QUOTENAME(DB_NAME())+ '.' /* Current Database */
        +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.'            
        +  QUOTENAME(name)  
        +  ' out D:\BCP\'  /* Path where BCP out files will be stored */
        +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_' 
        +  REPLACE(name,' ','') 
        + '.dat -T -E -SServerName\Instance -n' /* ServerName, -E will take care of Identity, -n is for Native Format */
    from sys.tables
    where is_ms_shipped = 0 and name <> 'sysdiagrams'                       /* sysdiagrams is classified my MS as UserTable and we dont want it */
    /*and schema_name(schema_id) <> 'unwantedschema'    */                             /* Optional to exclude any schema  */
    order by schema_name(schema_id)
  2. उस बैट फ़ाइल को चलाएं जो आपके द्वारा निर्दिष्ट फ़ोल्डर में .dat फाइलें उत्पन्न करेगी।

  3. स्क्रिप्ट पर नीचे चलाएँ

    --- Execute this on the destination server.database from SSMS.
    
    --- Make sure the change the @Destdbname and the bcp out path as per your environment.
    
    declare @Destdbname sysname
    set @Destdbname = 'destinationDB' /* Destination Database Name where you want to Bulk Insert in */
    select 'BULK INSERT ' 
    /*Remember Tables must be present on destination database */ 
    + QUOTENAME(@Destdbname) + '.' 
    + QUOTENAME(SCHEMA_NAME(SCHEMA_ID)) 
    + '.' + QUOTENAME(name) 
    + ' from ''D:\BCP\' /* Change here for bcp out path */ 
    + REPLACE(SCHEMA_NAME(schema_id), ' ', '') + '_' + REPLACE(name, ' ', '') 
    + '.dat'' with ( KEEPIDENTITY, DATAFILETYPE = ''native'', TABLOCK )' 
    + char(10) 
    + 'print ''Bulk insert for ' + REPLACE(SCHEMA_NAME(schema_id), ' ', '') + '_' + REPLACE(name, ' ', '') + ' is done... ''' 
    + char(10) + 'go'
       from sys.tables
       where is_ms_shipped = 0
    and name <> 'sysdiagrams' /* sysdiagrams is classified my MS as UserTable and we dont want it */
    and schema_name(schema_id) <> 'unwantedschema' /* Optional to exclude any schema */
        order by schema_name(schema_id) 
  4. तालिका में डेटा वापस डालने के लिए SSMS का उपयोग करके आउटपुट चलाएँ।

यह बहुत तेज़ bcp तरीका है क्योंकि यह Native मोड का उपयोग करता है।

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