2016-11-04 29 views
1

基本上我想用現有的表,可以稱之爲T1。我必須逐行取出該表並將不同的列插入2個獨立的表中。例如,C1,C2分成T2C3,C4分成T3用光標插入到2個表中,然後使用返回的scope_identity插入到另一個表中

在這兩個插入過程中,我需要確保我插入的值不存在。不幸的是有多個重複。它不是我的數據,它很髒。我必須照原樣做一噸鑄造。 機會很好,但不是100%,我想插入T2T3的列可能存在,而另一個則不存在。

一旦這些插入完成,我需要一個@SCOPE_Identity或另一種方式來唯一標識並保存兩個聲明的值自動遞增的ID,即T2T3創建。

這些需要被插入到T4這是一個查找表,大多隻存儲FK,它自己的ID,註釋和BIT。

我知道這是一項任務,但我真的需要一些幫助。 我修改了多個遊標和循環,但還沒有到那裏。 如果我想出一些解決方案,如果沒有人在我之前搞清楚。

編輯: 所以我解決了它。我發佈了易於閱讀和使用的代碼。如果有人想看它,評論,編輯等,它會在那裏。可能有更好的方法來做到這一點,所以如果可以的話請評論。

+0

向我們展示了您執行您的要求的最佳途徑,從您實際卡住的內容開始。 –

+0

根據你的解釋,光標不是必需的。唯一缺少的是你真實的表結構和數據類型。然後只能寫腳本。 – KumarHarsh

+0

我實際上已經全力以赴。我知道如果我把它作爲答案發布,我將不會得到選票或其他任何東西。不要太在意他們。我只是想知道哪個是最好的地方。 – user3779413

回答

0

這是用戶安全(我就稱呼它)的是我最終用來做我插入的版本。這實際上是爲導入數據集而設計的,如果沒有行級別的插入操作,在我看來會有些困難。當我跑這個時,大約需要2分鐘來插入50,000行。考慮到我的方式超過4列,一些列很大,我必須至少投一次(一些比其他更多),而且我必須使用LEFT或RIGHT進行各種切割以清除數據新表格。

Declare @Col1 varchar(50); 
DECLARE @Col2 varchar (50); 
DECLARE @col3 varchar (50); 
DECLARE @col4 varchar (50); 
DECLARE @T2ID int; 
DECLARE @T3ID int; 


DECLARE Cur1 CURSOR -- Create the cursor 
LOCAL FAST_FORWARD 
-- set the type of cursor. Note you could also use READ_ONLY and FORWARD_ONLY. 
-- You would have to performance test to see if you benifit from one or the other 

FOR 
--select FROM base table Table1 
    SELECT 
      Col1, Col2, Col3, Col4 
      FROM 
      Table1 
      WHERE Col1 IS NOT NULL AND Col3 IS NOT NULL 
      -- If the main columns are null then they are skipped. This was 
      -- required for my data but not necessarily yours. 
      OPEN Cur1 
      FETCH NEXT FROM Cur1 INTO 
      @Col1, @Col2, @Col3, @Col4; 
      -- Assigns values to variables declared at the top 


    WHILE @@FETCH_STATUS = 0 
    BEGIN 

       -- Select from table 2 
     SELECT @T2ID = T2ID 
     -- where some data in the table is = to the stored data we are searching for 
       FROM Table2 
       WHERE @Col1 = [Col1] 

       IF @@rowcount = 0 
        BEGIN 
         INSERT INTO T2 
          (Col1 
          ,Col2) 
         VALUES 
          (@Col1 
          ,@Col2) 

         SET @T2ID = SCOPE_IDENTITY(); 
        END; 



    -- Selects from Table3  
     SELECT @Col3 = Table3Col1 
       FROM Table3 
        IF @@rowcount = 0  
        -- If no rows are returned then proceed with insert 
         BEGIN 
          INSERT INTO Table3 
           (col3 
           ,col4) 
          VALUES   
      -- Uses values assigned to the variables from the cursor select 
           (@col3 
           ,@col4) 

          SET @T3ID = SCOPE_IDENTITY(); 
         END; 


      -- Inserts the gathered row id's into the lookup table 
      INSERT INTO Table4 
      (Table2ID 
      ,Table3ID) 
      VALUES (
      @Table2ID 
      ,@Table3ID) 

     FETCH NEXT FROM Cur1 INTO @Col1, @Col2, @col3, @col4; 


    END; 

CLOSE Cur1; 
DEALLOCATE Cur1; 

如果有人有改進報價請做。我樂於接受建議。 另外,除非有人要我,否則我不會接受我的回答是正確的,因爲可能有更好的答案。

0

我不熟悉你的表結構和數據量,但我會採取其他方式來解決這個問題。

  1. 創建包含需要在表T1T2
  2. 利用這個緩存表中插入填充所有表T1T2的數據緩存表,T3

我會嘗試這樣做,因爲在大多數情況下使用遊標速度很慢 - 您需要嘗試批量操作數據(一組行)。

如何做到這一點?

  1. 首先,你可以找到在T1最大身份ID和T2
  2. 然後,創建將會有以下的表:

    • T1_ID
    • T2_ID
    • C1
    • C2
    • C3
    • C4
    • ShouldBeInsertedInT1
    • ShouldBeInsertedInT2
  3. 現在,你必須使用從T1數據並生成T1_IDT2_ID領域來填充表。這是簡單的ROW_NUMBER功能+最大身份ID爲表T1T2

  4. 後的數據在緩存表,你必須以上升ShouldBeInsertedInT標誌執行兩個單獨的更新。您必須檢查緩衝表中的哪些列應插入T1T2表中。這可以通過連接,存在等來完成 - 它基本上取決於您的數據和業務邏輯。
  5. 如果你在這裏,你只需要執行插入。例如:

    SET IDENTITY_INSERT dbo.T1 ON 
    
    INSERT INTO T1 
    SELECT T1_ID, C1, C2 
    FROM bufffer 
    WHERE ShouldBeInsertedInT1 = 1; 
    
    SET IDENTITY_INSERT dbo.T1 OFF 
    
    SET IDENTITY_INSERT dbo.T2 ON 
    
    INSERT INTO T2 
    SELECT T2_ID, C3, C4 
    FROM bufffer 
    WHERE ShouldBeInsertedInT2 = 1; 
    
    SET IDENTITY_INSERT dbo.T2 OFF 
    
    INSERT INTO T3 
    SELECT T1_ID, T2_ID 
    FROM bufffer; 
    

這僅僅是一個概念,所以你必須改變這種代碼。請注意,整個過程可能需要在交易中才能確保T1T2的最大身份ID不會更改。

+0

這聽起來像個好主意。我試試看。只有幾件事 1.'T1'是源表 2.T2'是第一個具有幾百個副本的主表 3.'T3'是具有數千個副本的輔助表 4.'T4 '作爲字典查找表) 如果它非常簡單,所有信息都是唯一的,那麼這可能會起作用,但是再次如此,將3個單獨的分類插入。 – user3779413

相關問題