在没有ID的情况下使INSERT INTO尽可能作为错误/重复证明

时间:2019-02-19 17:38:49

标签: sql sql-server stored-procedures insert where

我有一个存储过程,它从tableA插入到tableB。每次执行过程时(因为tableA会不断更新,因此在运行过程时它将丢失的数据添加到B中),无论如何,它将A的全部内容插入到B中。

因此,我在插入中添加了一个WHERE语句,用于根据添加记录的时间戳过滤“较旧的数据”(插入新记录,其中来自tableA的时间戳大于一个记录) tableB上的)。该表没有唯一的标识符,因此我有点想使过滤器尽可能地安全,基本上我唯一可以考虑的就是时间戳。我已经尝试了一些解决方法,但是所有方法都有其缺点(在每个代码块中都有注释)。

INSERT INTO TABLEB (VALUES)
    SELECT A.VALUES
    FROM A 
    WHERE (SELECT MAX(TIMESTAMP) FROM TABLEB) < (SELECT MAX(TIMESTAMP) FROM TABLEA)

--THIS DOESN'T EVEN WORK
INSERT INTO TABLEB (VALUES)
    SELECT A.VALUES
    FROM A 
    WHERE A.TIMESTAMP BETWEEN (SELECT MAX(TIMESTAMP) FROM TABLEB) AND (SELECT MAX(TIMESTAMP) FROM TABLEA)

--IF RUN TWICE IT WILL RUN ON RECORDS CONTAINING TIMESTAMPS WITH THOSE VALUES
INSERT INTO TABLEB (VALUES)
    SELECT A.VALUES
    FROM A 
    WHERE A.TIMESTAMP BETWEEN (SELECT MAX(TIMESTAMP) FROM TABLEB) AND (SELECT MAX(TIMESTAMP) FROM TABLEA)
      AND A.TIMESTAMP <> (SELECT MAX(TIMESTAMP) FROM TABLEA)

--THIS WILL EFFECTIVELY SKIP RECORDS WITH THE TIMESTAMP FROM TABLEA BUT RUN TWICE WILL DUPLICATES THE ONES WITH TIMESTAMP FROM B

INSERT INTO TABLEB (VALUES)
    SELECT A.VALUES
    FROM A 
    WHERE A.TIMESTAMP BETWEEN (SELECT MAX(TIMESTAMP) FROM TABLEB) AND (SELECT MAX(TIMESTAMP) FROM TABLEA)
      AND A.TIMESTAMP <> (SELECT MAX(TIMESTAMP) FROM TABLEA)
      AND A.TIMESTAMP <> (SELECT MAX(TIMESTAMP) FROM TABLEB)

--THIS WILL SKIP DATA WITH THE TIMESTAMP FROM B

对于在运行中一次执行并跳过重复行的逻辑的任何帮助,都将受到赞赏。

3 个答案:

答案 0 :(得分:1)

我不确定您的问题是什么,但这应该可以解决。您检查表B中插入的最后一个是什么,然后获取所有新记录。

INSERT INTO TABLEB (VALUES)
    SELECT A.VALUES
    FROM A 
    WHERE TIMESTAMP > (SELECT MAX(TIMESTAMP) FROM TABLEB)

答案 1 :(得分:0)

在表A的每个插入上插入所有记录非常昂贵。如果使用的是T-SQL(SQL服务器),则可以使用“ Scope_Identity”命令。您需要在同一调用中在两个表中添加每个记录。将值添加到表A,然后添加到表B。

以下是示例:

INSERT INTO TABLEA (column-names) 
VALUES (values)

DECLARE @LAST_RECORD_ID INT=0

SELECT @LAST_RECORD_ID = SCOPE_IDENTITY()

INSERT INTO TABLEB (column-names) 

SELECT 
    (column-names)
FROM TABLEA WHERE TABLEA.ID = @LAST_RECORD_ID

答案 2 :(得分:0)

您需要在表A中具有一个带有时间戳类型的版本列,并在表B中具有一个具有varbinary(8)类型的对应列。在这种假设下,以下代码必须有效:

INSERT INTO TABLEB (VALUES)
    SELECT A.VALUES
    FROM A 
    WHERE A.Version > (SELECT MAX(Version) FROM TABLEB)