使用光标插入 2 tables,然后使用返回的 scope_identity 插入另一个 table

Insert into 2 tables with cursor, then use returned scope_identity to insert into another table

基本上我想使用现有的 table,我们称它为 T1。我必须逐行获取 table,并将不同的列插入到 2 个单独的 table 中。例如,C1C2 变成 T2C3C4 变成 T3

在这两个插入过程中,我需要确保我插入的值不存在。不幸的是有多个重复项。这不是我的数据,而且很脏。我必须按原样进行大量铸造。 我想插入 T2T3 的列可能存在而另一个不存在,但不是 100%。

完成这些插入后,我需要一个 @SCOPE_Identity 或其他方法来唯一标识并在两个声明的值中保存 T2T3 创建的自动递增 ID。

然后需要将这些插入到 T4 中,这是一个查找 table,主要只存储 FK、它自己的 ID、注释和 BIT。

我知道这是一项艰巨的任务,但我真的需要一些帮助。 我已经修改了多个游标和循环,但还没有到那里。 如果我想出了一些办法,我会 post 一个解决方案,如果在我之前没有人想出的话。

编辑: 所以我解决了。我已经 post 编辑了我的代码,使其易于阅读和用作答案。如果有人想查看它、发表评论、进行编辑等,它就会在那里。可能有更好的方法,如果可以的话请评论。

我不熟悉你的table结构和数据量,但我会采取其他方法来解决这个问题。

  1. 创建一个缓冲区table,用于存放需要插入tableT1T2
  2. 的数据
  3. 使用此缓冲区 table 填充所有 tables T1T2T3

我会尝试这样做,因为在大多数情况下使用游标很慢 - 您需要尝试批量操作数据(行组)。

如何做到这一点?

  1. 首先可以在T1T2
  2. 中找到最大身份ID
  3. 然后,创建一个 table 将具有以下列:

    • T1_ID
    • T2_ID
    • C1
    • C2
    • C3
    • C4
    • ShouldBeInsertedInT1
    • ShouldBeInsertedInT2
  4. 现在,您必须使用来自 T1 的数据填充 table 并生成 T1_IDT2_ID 字段。这是简单的ROW_NUMBER函数+最大身份ID为tableT1T2.

  5. 数据进入缓冲区table后,您必须执行两次单独的更新才能升起ShouldBeInsertedInT标志。您必须检查缓冲区 table 中的哪些列应该插入到 T1T2 table 中。这可以通过连接、存在等来完成——这基本上取决于您的数据和业务逻辑。
  6. 如果你在这里,你只需要执行插入。例如:

    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 未更改。

这是我最终用于插入的用户安全版本(我就这么称呼它)。这实际上是为导入数据集而设计的,在我看来,如果没有行级插入,这些数据集会有些困难。当我 运行 插入 50, 000 行大约需要 2 分钟。请记住,我有超过 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;

如果有人要提供改进,请提供。我愿意接受建议。 另外,除非有人要我这样做,否则我不会接受我的答案是正确的,因为可能会有更好的答案。