2010-02-06 10 views
7

मैं फ़ाइल में परिभाषित रिश्तों को बनाए रखते हुए एसएसआईएस का उपयोग करते हुए एसक्यूएल सर्वर पर एकाधिक फाइलों में एक फ़ाइल (लाखों + रिकॉर्ड के साथ) से डेटा लोड करने की कोशिश कर रहा हूं।एसएसआईएस का उपयोग विदेशी कुंजी रिश्ते को रखते हुए एकाधिक टेबल्स लोड करना

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

फ़ाइल:

EmployeeName<tab>OfficeHistory<tab>JobLevelHistory 
John Smith<tab>501<tab>Engineer 
John Smith<tab>601<tab>Senior Engineer 
John Smith<tab>701<tab>Manager 
Alex Button<tab>601<tab>Senior Assistant 
Alex Button<tab>454<tab>Manager 

अगर मेरे कार्यालय डेटाबेस स्कीमा निम्न तालिकाओं है:

Employee (nId, name) 
Office (nId, number) 
JobTitle (nId, titleName) 
Employee2Office (nEmpID, nOfficeId) 
Employee2JobTitle (nEmpId, nJobTitleID) 

मैं SSIS कर्मचारी के लिए स्वत: उत्पन्न आईडी ऊपर स्कीमा में फ़ाइल लोड करने के लिए उपयोग कर सकते कैसे, कार्यालय और जॉबटाइटल और कर्मचारी और कार्यालयों, और कर्मचारी और नौकरी टाइटल के बीच संबंध बनाए रखना?

तो इस मामले में। टेबल दिखना चाहिए:

Employee 
1 John Smith 
2 Alex Button 

Office 
1 501 
2 601 
3 701 
4 454 

JobTitle 
1 Engineer 
2 Senior Engineer 
3 Manager 
4 Senior Assistant 

Employee2Office 
1 1 
1 2 
1 3 
2 2 
2 4 

Employee2JobTitle 
1 1 
1 2 
1 3 
2 4 
2 3 

मैं SSIS करने के लिए एक नौसिखिया हूँ और एक डेटा प्रवाह कार्य निष्पादित करते समय चारों ओर स्वचालित रूप जेनरेट आईडी और स्थापित करने के लिए विदेशी कुंजी रिश्तों के साथ नहीं खेला है। कोई भी संकेतक प्रशंसनीय होंगे।

धन्यवाद!

+0

मेरा पहला सवाल यह है कि आपके आयात को कैसे पता चलेगा कि एक ही नाम वाले दो रिकॉर्ड एक ही व्यक्ति या अलग-अलग लोग हैं? चूंकि नाम अद्वितीय नहीं हैं, इसलिए आपको यह जानने के लिए फ़ाइल में एक तरीका होना चाहिए कि कौन सा है। – HLGEM

+0

अच्छा सवाल - मान लें कि हम इस परिदृश्य के लिए मानते हैं, कर्मचारी का नाम अद्वितीय है। तो इस संगठन में केवल एक ही जॉन स्मिथ होगा। – mvm

उत्तर

1

आप सुनिश्चित करें कि आपके रेफेरेंन्शिअल सत्यनिष्ठा डेटा है कि आप लोड करने के लिए, आप एक स्क्रिप्ट कार्य में विदेशी कुंजी की कमी निष्क्रिय कर सकते हैं, तो डेटा समानांतर डेटा लोड के साथ और डेटा लोड खत्म होने के बाद प्रवाह पर अमल चाहते हैं के साथ ठीक है कर रहे हैं, सक्षम बाधाएं फिर से यदि डेटा के साथ कुछ सही नहीं है, तो ऑपरेशन विफल हो जाएगा। हालांकि आपको रोलबैक या क्लीनअप रणनीति तैयार करनी होगी।

अन्य विकल्प धारावाहिक रास्ते में डेटा लोड करने के लिए, मुख्य टेबल से शुरू करने और बच्चे को टेबल पर खत्म कर सिर्फ है। मुझे लगता है कि यह 'सुरक्षित' विकल्प है, क्योंकि यह ईटीएल लोड के समय इन तालिकाओं का उपयोग करने वाले अन्य उपयोगकर्ताओं को आपकी डेटा अखंडता का खुलासा नहीं करता है। मैं इस विकल्प को पसंद करूंगा।

+0

पहले विकल्प के लिए, मैं डेटा लोड करने के बाद Employee2JobTitle और Employee2Office में मैपिंग कैसे स्थापित करूं? उपयोगकर्ताओं को डेटा का खुलासा करना मेरी दुनिया में एक प्रासंगिक मुद्दा नहीं है - दूसरा विकल्प बड़े डेटा सेट के लिए समय लेने वाला होगा। – mvm

0

आप एक संग्रहीत प्रक्रिया है कि बुनियादी तालिकाओं (कर्मचारी, कार्यालय और JobTitle) में पहली डालने डेटा तो पंक्ति द्वारा अपनी फ़ाइल पंक्ति पढ़ लिख सकते हैं। इसके बाद आपको पहचान प्राप्त करने और संबंध तालिकाओं में डेटा डालने के लिए अपनी मूल सारणी खोजनी चाहिए।

एक पहचान स्तंभ के साथ अपने डेटाबेस में कर्मचारी, कार्यालय और कार्य शीर्षक तालिकाओं को परिभाषित करें, ताकि आईडी करेंगे: यह थोड़ा मुश्किल है केवल पाठ से समझाने के लिए, लेकिन मैं इसे एक शॉट दे देंगे -

1

यहाँ है कैसे स्वचालित रूप से उत्पन्न हो।

बिना कई-से-अनेक तालिकाओं (पहचान की जरूरत या उपयोगी नहीं है)

अपने लघु उद्योगों डाटा प्रवाह में परिभाषित करें, आप क्रम में आईडी स्थापित करने के लिए गुजरता के एक जोड़े में ऐसा करने के लिए, है डेटाबेस पहले, फिर वापस आएं और कई से कई पंक्तियां डालें।

एक डाटा प्रवाह बनाओ:

  1. एक मल्टी कास्ट के साथ तीन प्रतियों में कोई डेटा स्रोत रखो फ़ाइल में पढ़ने के लिए
  2. यह विभाजन। एक कर्मचारी, एक कार्यालय, एक खिताब के लिए होगा।
  3. प्रत्येक के लिए, एक क्रमबद्ध करें (यह आमतौर पर नो-नो है, लेकिन चूंकि स्रोत टेक्स्ट है और डेटाबेस नहीं है, इसलिए हमें वहां जाना होगा)। तीन फ़ील्ड में से केवल एक के माध्यम से गुजरने के लिए सॉर्ट करें, और डुप्लिकेट को हटाने के लिए क्रम में विकल्प को चेक करें। यह प्रत्येक आधार तालिका के लिए एक अनूठी सूची (जैसे विशिष्ट चयन) बनाता है।
  4. प्रत्येक तालिका से जुड़े तीनों में से प्रत्येक के लिए एक गंतव्य रखें।

पहले डेटा प्रवाह के बाद, दूसरा डेटा प्रवाह जोड़ें। यह एक बहुत-से-अनेक संबंध पंक्तियों

  1. से स्थापित हो जाएगा पढ़ें कोई डेटा स्रोत
  2. के साथ फ़ाइल के लिए लुक कि डेटाबेस में कर्मचारी का नाम लिए पाता है और कर्मचारी आईडी रिटर्न जोड़ें। यह आपको उपरोक्त जेनरेट किया गया कर्मचारी आईडी प्राप्त करता है। (इसे आमतौर पर सरोगेट कुंजी के लिए व्यवसाय या प्राकृतिक कुंजी द्वारा लुकअप कहा जाता है)
  3. डेटाबेस में शीर्षक ढूंढने के लिए एक लुकअप जोड़ें और शीर्षक आईडी
  4. डेटाबेस में Office के लिए एक लुकअप जोड़ें और Office को वापस लौटाता है आईडी
  5. फिर, दो प्रतियां, कर्मचारी ऑफिस के लिए और एक कर्मचारी शीर्षक
  6. के लिए, तर्क आप की जरूरत पर निर्भर करता है शायद क्रमबद्ध, फिर से उपयोग करते हैं, इन deduplicate करने में बहु डाली परिणाम (विस्तार पर निर्भर करता है इनपुट से आप सामान्यीकरण कैसे कर रहे हैं)
  7. परिणाम दो गंतव्यों के साथ कई से कई तालिकाओं में रखें।
2

एक दिलचस्प सवाल है। यहां बताया गया है कि मैं इसे कैसे करूं (एसक्यूएल सर्वर 2005)। (मैं यह सिर्फ एक बार एक मासिक काम है और न मानते हुए कर रहा हूँ, इसलिए मैं repeatability के लिए कोड जोड़ा।)

  1. कर्मचारी के लिए तीन चर बनाएँ, JobTitle और कार्यालय तालिका (type = वस्तु)
  2. संबंधित चर में उन तीन तालिकाओं के लिए पंक्तियों का चयन करने के लिए तीन एसक्यूएल कार्यों का उपयोग करें।
  3. डेटाफ़्लो कार्य जोड़ें।
  4. एक फ्लैट फ़ाइल गंतव्य का उपयोग कर अपनी फ्लैट फ़ाइल से चुनें।
  5. आउटपुट फ्लैट फ़ाइल में तीन कॉलम इनपुट के रूप में एक स्क्रिप्ट घटक में जाता है, स्क्रिप्ट में आयातित तीन तालिका चर, स्क्रिप्ट घटक में पांच आउटपुट प्रत्येक एक ही बहिष्करण समूह संख्या और इनपुट के लिए सिंक्रोनस के रूप में चिह्नित इनपुट उस आउटपुट, सात नए कॉलम (प्रत्येक आउटपुट के लिए एएमपी एक के लिए 3, इसमें नौकरी के लिए 2, कार्यालय के लिए 2), आउटपुट में जोड़ा गया, और निम्न कोड के साथ (System.xml.dll को एक संदर्भ जोड़ा जाना था यह सब काम करने के लिए):।

    Imports System 
    Imports System.Data 
    Imports System.Math 
    Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper 
    Imports Microsoft.SqlServer.Dts.Runtime.Wrapper 
    Imports System.Collections 
    Imports System.Data.OleDb 
    
    Public Class ScriptMain 
        Inherits UserComponent 
    
        Private da As New OleDbDataAdapter 
        Private emp As New DataTable 
        Private emph As New Hashtable() 
        Private job As New DataTable 
        Private jobh As New Hashtable() 
        Private off As New DataTable 
        Private offh As New Hashtable() 
        Private maxempid As Integer 
        Private maxjobid As Integer 
        Private maxoffid As Integer 
    
        Public Overrides Sub PreExecute() 
         maxempid = 0 
         maxjobid = 0 
         maxoffid = 0 
         da.Fill(emp, Me.Variables.EmpTab) 
         For Each dr As DataRow In emp.Rows 
          emph.Add(dr.Item("Name"), dr.Item("nID")) 
          If (CInt(dr.Item("nID").ToString) > maxempid) Then 
           maxempid = CInt(dr.Item("nID").ToString) 
          End If 
         Next 
         da.Fill(job, Me.Variables.JobTab) 
         For Each dr As DataRow In job.Rows 
          jobh.Add(dr.Item("titleName"), dr.Item("nID")) 
          If (CInt(dr.Item("nID").ToString) > maxempid) Then 
           maxjobid = CInt(dr.Item("nID").ToString) 
          End If 
         Next 
         da.Fill(off, Me.Variables.OffTab) 
         For Each dr As DataRow In off.Rows 
          offh.Add(dr.Item("number"), dr.Item("nID")) 
          If (CInt(dr.Item("nID").ToString) > maxempid) Then 
           maxoffid = CInt(dr.Item("nID").ToString) 
          End If 
         Next 
         emp.Dispose() 
         job.Dispose() 
         off.Dispose() 
         da.Dispose() 
         MyBase.PreExecute() 
        End Sub 
    
    Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer) 
    
        If Not emph.ContainsKey(Row.EmployeeName) Then 
         maxempid += 1 
         emph.Add(Row.EmployeeName, maxempid) 
         Row.EmpId = maxempid 
         Row.Emp2Id = maxempid 
         Row.Emp3Id = maxempid 
         Row.DirectRowToEmployee() 
        Else 
         Row.EmpId = CInt(emph.Item(Row.EmployeeName).ToString) 
         Row.Emp2Id = CInt(emph.Item(Row.EmployeeName).ToString) 
         Row.Emp3Id = CInt(emph.Item(Row.EmployeeName).ToString) 
        End If 
        If Not jobh.ContainsKey(Row.JobLevelHistory) Then 
         maxjobid += 1 
         jobh.Add(Row.JobLevelHistory, maxjobid) 
         Row.JobId = maxjobid 
         Row.Job2Id = maxjobid 
         Row.DirectRowToJobTitle() 
        Else 
         Row.JobId = CInt(jobh.Item(Row.JobLevelHistory).ToString) 
         Row.Job2Id = CInt(jobh.Item(Row.JobLevelHistory).ToString) 
        End If 
        If Not offh.ContainsKey(Row.OfficeHistory) Then 
         maxoffid += 1 
         offh.Add(Row.OfficeHistory, maxoffid) 
         Row.OffId = maxoffid 
         Row.Off2Id = maxoffid 
         Row.DirectRowToOfficeNumber() 
        Else 
         Row.OffId = CInt(offh.Item(Row.OfficeHistory).ToString) 
         Row.Off2Id = CInt(offh.Item(Row.OfficeHistory).ToString) 
        End If 
        Row.DirectRowToEmp2Job() 
        Row.DirectRowToEmp2Off() 
    End Sub   
    End Class 
    
  6. इस स्क्रिप्ट से परिणाम (स्क्रिप्ट इनपुट डेटा में आईडी नए मूल्यों के लिए के उत्पन्न करता है यह की preexecute हिस्से में hashtables में मौजूदा तालिका को लोड करके करता है। स्क्रिप्ट, फिर नाम के अस्तित्व की जांच करके और उसके आधार पर या तो अधिकतम को बढ़ाता है और इसे हैश में जोड़ता है, यदि यह हैश में जोड़ता है, तो यह पंक्ति को उपयुक्त (emp, job, या off) आउटपुट में भी जोड़ता है, या प्रत्येक पंक्ति के लिए हैश से maxid पुनर्प्राप्त करता है।) ऊपर की स्थिति के बावजूद सभी पंक्ति दो शेष आउटपुट (emp2job और emp2off) पर लिखा जाएगा।

  7. अगला, देखने के लिए डेटाफ्लो भेजें (गंतव्य तालिका में मौजूदा पंक्तियों की जांच करने के लिए, फिर गंतव्य ओल्डब कनेक्टर (एमएमपी, नौकरी, और पहचान आवेषण के लिए बॉक्स को चेक करें, emp2job और emp2off चेक बाधाओं को अनचेक करें)।
+1

ग्रेट उत्तर और अच्छा कोडिंग उदाहरण। – ajdams

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