Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 是否可以忽略insert中的唯一约束并插入不存在的内容?_Sql Server_Tsql - Fatal编程技术网

Sql server 是否可以忽略insert中的唯一约束并插入不存在的内容?

Sql server 是否可以忽略insert中的唯一约束并插入不存在的内容?,sql-server,tsql,Sql Server,Tsql,我需要在一个N:N关系表中插入许多行,但是如果存在一个键IDTable1,IDTable2,它将抛出一个异常,并且不会插入其余的键 我试图以这种方式插入数据: insert into MyTable(IDTable1, IDTable2) VALUES(1,2), VALUES(1,3), VALUES(2,4), VALUES(4,5), VALUES(5,7); begin try insert into MyTable(IDTable1, IDTable2) VALUES(1,2), V

我需要在一个N:N关系表中插入许多行,但是如果存在一个键IDTable1,IDTable2,它将抛出一个异常,并且不会插入其余的键

我试图以这种方式插入数据:

insert into MyTable(IDTable1, IDTable2)
VALUES(1,2),
VALUES(1,3),
VALUES(2,4),
VALUES(4,5),
VALUES(5,7);
begin try
insert into MyTable(IDTable1, IDTable2)
VALUES(1,2),
VALUES(1,3),
VALUES(2,4),
VALUES(4,5),
VALUES(5,7);
end try
begin catch
end catch
问题是,例如,如果存在Maple 1,3,其余的键不会插入,但我希望如果存在键,忽略它并插入不存在的键

此外,我还尝试了try/catch,方法如下:

insert into MyTable(IDTable1, IDTable2)
VALUES(1,2),
VALUES(1,3),
VALUES(2,4),
VALUES(4,5),
VALUES(5,7);
begin try
insert into MyTable(IDTable1, IDTable2)
VALUES(1,2),
VALUES(1,3),
VALUES(2,4),
VALUES(4,5),
VALUES(5,7);
end try
begin catch
end catch
但问题是相同的,我得到0行受影响

是否可以忽略现有密钥并插入不存在的密钥

谢谢。

一种方法是合并

这也可以通过插入…选择与不存在一起执行:

Table 'MyTable'. Scan count 1, logical reads 17, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 11, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
编辑:

下面是一个左外连接方法:

对于这个特定的表、索引和数据,基于最少的逻辑读取,MERGE的性能最好。SQL Server 2017中这3种方法的统计IO结果如下:

合并:

Table 'MyTable'. Scan count 0, logical reads 22, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
不存在:

Table 'MyTable'. Scan count 1, logical reads 17, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 11, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
左外连接:

Table 'MyTable'. Scan count 1, logical reads 17, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 11, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
我在集群唯一约束下观察到了类似的结果

但是,从性能的角度来看,我不能概括合并始终是最好的方法。理想情况下,SQLServer将为语义相同的查询生成相同的计划,尽管在实践中并不总是这样。当性能受到特别关注时,您需要检查执行计划并使用代表性数据测试性能

一种方法是合并

这也可以通过插入…选择与不存在一起执行:

Table 'MyTable'. Scan count 1, logical reads 17, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 11, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
编辑:

下面是一个左外连接方法:

对于这个特定的表、索引和数据,基于最少的逻辑读取,MERGE的性能最好。SQL Server 2017中这3种方法的统计IO结果如下:

合并:

Table 'MyTable'. Scan count 0, logical reads 22, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
不存在:

Table 'MyTable'. Scan count 1, logical reads 17, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 11, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
左外连接:

Table 'MyTable'. Scan count 1, logical reads 17, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 11, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
我在集群唯一约束下观察到了类似的结果


但是,从性能的角度来看,我不能概括合并始终是最好的方法。理想情况下,SQLServer将为语义相同的查询生成相同的计划,尽管在实践中并不总是这样。当性能受到特别关注时,您需要检查执行计划并使用代表性数据测试性能

在SQL中,您必须准备好一次插入整个列表,而不是一次尝试一个,然后移动到下一个

这应该对你有好处。它加入到您插入的表中,忽略任何找到匹配项的内容

INSERT INTO [MyTable] ([IDTable1], [IDTable2])
SELECT [IDTable1], [IDTable2]
FROM [MySource] as source
    LEFT JOIN [MyTable] AS duplicates
        ON source.[IDTable1] = duplicates.[IDTable1]
             AND source.[IDTable2] = duplicates.[IDTable2]
WHERE duplicates.[IDTable1] IS NULL

在SQL中,您必须准备好一次插入整个列表,而不是尝试一个,然后移动到下一个

这应该对你有好处。它加入到您插入的表中,忽略任何找到匹配项的内容

INSERT INTO [MyTable] ([IDTable1], [IDTable2])
SELECT [IDTable1], [IDTable2]
FROM [MySource] as source
    LEFT JOIN [MyTable] AS duplicates
        ON source.[IDTable1] = duplicates.[IDTable1]
             AND source.[IDTable2] = duplicates.[IDTable2]
WHERE duplicates.[IDTable1] IS NULL

使用“合并”或“插入…”选择…不存在的位置。或在唯一索引上设置“忽略重复”键。@DavidBrowne Microsoft,是的,也可以使用“忽略重复”键,但我个人会避免使用它。通常情况下,插入dup会引发主键冲突,而不是默默地忽略它。使用“合并”或“插入…”选择…不存在的位置。或者在唯一索引上设置“忽略dup”键。@DavidBrowne Microsoft,是的,也可以使用“忽略dup”键,但我个人会避免它。人们通常希望插入dup会引发主键冲突,而不是默默地忽略它?也许是在表演或其他方面?非常感谢。@阿尔瓦罗加西亚,这些查询在语义上是相同的。我用性能详细信息更新了答案。不过要小心使用合并。它有更好的性能,但您需要检查它是否存在任何已知问题,这取决于您是否值得为此付出努力。MERGE首次推出时存在一些问题,目前尚不清楚这些问题是否在2016年得到解决,您也没有指定使用的版本。通常我发现使用左连接更好,不必担心。以下是供参考的问题这两个选项之间有什么不同?也许是在表演或其他方面?非常感谢。@阿尔瓦罗加西亚,这些查询在语义上是相同的。我用性能详细信息更新了答案。不过要小心使用合并。它有更好的性能,但您需要检查它是否存在任何已知问题,这取决于您是否值得为此付出努力。MERGE首次推出时存在一些问题,目前尚不清楚这些问题是否在2016年得到解决,您也没有指定使用的版本。通常我发现使用左连接更好,不必担心。以下是供参考的问题