2016-11-04 30 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

相关问题