如何防止将重复数据插入到值为多个的 SQL Server 表中

Posted

技术标签:

【中文标题】如何防止将重复数据插入到值为多个的 SQL Server 表中【英文标题】:How can I prevent inserting duplicate data into a SQL Server table where value is multiple 【发布时间】:2021-07-31 19:45:50 【问题描述】:

我声明了一些需要插入SQL的数据,我应该如何检查SQL中的数据以防止相同的数据插入到表中?

123(AA) 已上传,123(BB) 是新受邀者。 在这种情况下,服务器应该只上传 123(BB)。

 declare @inviteename VARCHAR(500) = 'aa,bb' ,@inviteephoneno VARCHAR(500) = '123,45',@Code varchar(10)='123', @CustomerID VARCHAR(50) = 10  

   DECLARE @tbl TABLE (
inviteename VARCHAR(100), 
inviteephoneno VARCHAR(100)
);

INSERT INTO @tbl ( inviteename, inviteephoneno) select  @inviteename, @inviteephoneno;

   DECLARE @temp TABLE (
inviteename VARCHAR(100), 
inviteephoneno VARCHAR(100),
CustomerID VARCHAR(100)
);

;WITH cte1 AS
(
    SELECT  value AS inviteename , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS seq
    FROM @tbl CROSS APPLY STRING_SPLIT(inviteename, ',')
), cte2 AS
(
    SELECT  value AS inviteephoneno , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS seq
    FROM @tbl CROSS APPLY STRING_SPLIT(inviteephoneno, ',')
)

INSERT INTO @temp ( inviteename, inviteephoneno,CustomerID)
SELECT cte1.inviteename, cte2.inviteephoneno,@CustomerID   FROM cte1 INNER JOIN cte2 ON cte2.seq = cte1.seq; 

if not  exists (select 1 from test a where a.inviteename= (select InviteeName from @temp a where a.CustomerID=@CustomerID)
 and a.InviteeMobileNumber = (select InviteeMobileNumber from @temp a where a.CustomerID=@CustomerID))    
  begin
  INSERT dbo.test (InviteeName ,InviteeMobileNumber ) 
   SELECT a.inviteename, a.inviteephoneno  FROM @temp a 

  end

测试表

create table test ( 
id int identity(1,1)
, inviteename VARCHAR(100)
, inviteephoneno VARCHAR(100) );

【问题讨论】:

如果要停止重复值,请使用UNIQUE INDEXUNIQUE CONSTRAINT,但是,值'123(AA)''123(BB)' 不同/唯一,所以我不明白这里的问题。 你能为你的 dbo.test 表提供一个创建表吗 您应该尝试使用 MERGE 语句而不是 INSERT。它已经负责识别重复并为两种情况(重复和非重复)提供单独的执行路径。 【参考方案1】:

您可以使用merge

    create table test ( 
    id int identity(1,1)
    , inviteename VARCHAR(100)
    , InviteeMobileNumber VARCHAR(100) );
GO
     declare @inviteename VARCHAR(500) = 'aa,bb' 
     ,@inviteephoneno VARCHAR(500) = '123
     ,45',@Code varchar(10)='123'
     , @CustomerID VARCHAR(50) = 10  
    
       DECLARE @tbl TABLE (
    inviteename VARCHAR(100), 
    inviteephoneno VARCHAR(100)
    );
    
    INSERT INTO @tbl ( inviteename, inviteephoneno) select  @inviteename, @inviteephoneno;
    
       DECLARE @temp TABLE (
    inviteename VARCHAR(100), 
    inviteephoneno VARCHAR(100),
    CustomerID VARCHAR(100)
    );
    
    ;WITH cte1 AS
    (
        SELECT  value AS inviteename , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS seq
        FROM @tbl CROSS APPLY STRING_SPLIT(inviteename, ',')
    ), cte2 AS
    (
        SELECT  value AS inviteephoneno , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS seq
        FROM @tbl CROSS APPLY STRING_SPLIT(inviteephoneno, ',')
    )
    
    INSERT INTO @temp ( inviteename, inviteephoneno,CustomerID)
    SELECT cte1.inviteename, cte2.inviteephoneno,@CustomerID   FROM cte1 INNER JOIN cte2 ON cte2.seq = cte1.seq; 
    MERGE dbo.test AS T
USING @temp AS S
ON (T.inviteename = S.inviteename AND T.InviteeMobileNumber = S.inviteephoneno) 
WHEN NOT MATCHED BY TARGET  
    THEN INSERT (InviteeName ,InviteeMobileNumber) VALUES(S.inviteename, S.inviteephoneno)
OUTPUT $action, Inserted.*;
GO
$行动 |编号 |受邀者姓名 |被邀请人手机号码 :-------- | -: | :------------ | :----------------- 插入 | 1 |啊 | 123 插入 | 2 | bb | 45
SELECT * FROM test
GO
编号 |受邀者姓名 |被邀请人手机号码 -: | :------------ | :----------------- 1 |啊 | 123 2 | bb | 45

db小提琴here

【讨论】:

以上是关于如何防止将重复数据插入到值为多个的 SQL Server 表中的主要内容,如果未能解决你的问题,请参考以下文章

防止 SQL 表中的重复值

如何防止相同的 id 将数据插入数据库(多用户)

如何使用 SQL 将重复数据插入 BigQuery 表

触发插入 - 防止插入重复 ID

mysql 插入数据如何防止重复

SQL多个主键的表,插入数据有重复时,查询数据的重复值?