将T1中当前不在T2中的所有行插入T2

时间:2017-12-01 15:58:14

标签: sql-server left-join sql-insert

我正在尝试将T1中的所有记录插入到当前不在T2中的T2

我在循环中尝试过,因为我从存储过程生成代码作为T2的标识符

declare     @Part           VARCHAR(255),
            @GenValue       VARCHAR(255),
            @x              INT
set @x = (select count(*) from T1)  
WHILE @x >=0

BEGIN
    EXEC [dbo].[usp_GenInd] @GenValue OUT,@GencCode = 'TKM', @GencIncrement = 1


     set @Part = @GencValue

    INSERT INTO dbo.T2
    SELECT  @Part                           AS  [part],
            [Prod_Code] + Column_Header     AS  [identifier],
            [part_rev]                      =   NULL,
            '!'                             AS  [u_version],
            a.[Descr]                           AS  [descr],
            GETDATE()                       AS  [last_updated],
            'ME'                            AS  [last_upd_user],
            'EA'                            AS  [basic_unit],
            [source]                        =   NULL,
            'MAIN'                          AS  [level_1],
            'GROUP'                         AS  [level_2],
            'ME'                            AS  [user_created],
            '20'                            AS  [status],
            [Prod_Code]                     AS  [master_part],
            [drawing_no]                    =   NULL

    FROM [dbo].T1 a
    LEFT JOIN dbo.T2 b
        ON a.Prod_Code + a.Column_Header = b.part
    WHERE b.part is null

END

我一直收到错误说T2上的主键违规,这是我从存储过程生成的@part变量。

也很慢,我认为null上的左边连接插入比光标更快。

T1中只有67行

感谢您提前帮助

3 个答案:

答案 0 :(得分:1)

不 - 如果必须继续使用此存储过程生成主键值,请返回游标。您添加到此脚本的逻辑错误是insert语句。它没有从T1中选择一个特定的行 - 它选择T1中T2中不存在的所有行(假设逻辑是正确的 - 我不打算对它进行评估)。据推测,您必须调用过程usp_GenInd为T1中的每一行生成PK值。此外,你永远不会减少@x - 所以你有一个无限循环。

注意措辞 - “不存在”。通常,当查询匹配(尽可能接近)代码的意图时,我发现更容易理解未记录的逻辑。你的左连接逻辑是不存在的 - 只是更难以弄清楚。并且您的连接逻辑也存在潜在问题,无法检查是否存在。 'AA'+'B'='A'+'AB' - 但列包含不同的值。小心假设。

答案 1 :(得分:0)

我会尝试类似的事情:

;WITH cte AS (
 SELECT  your needed data
 FROM [dbo].T1
 EXCEPT
 SELECT  already existing data
 FROM [dbo].T2
)
INSERT INTO dbo.T2
SELECT *
FROM cte

答案 2 :(得分:0)

您的JOIN逻辑存在缺陷。

在你的INSERT中你有这个:

INSERT INTO dbo.T2
SELECT  @Part                           AS  [part],
        [Prod_Code] + Column_Header     AS  [identifier],

将@Part插入[part]

但是当你进行JOIN以排除现有行时,你就有了这个:

   LEFT JOIN dbo.T2 b
        ON a.Prod_Code + a.Column_Header = b.part

要排除现有行,您应该加入@part=b.part